The DateTime class seems redundant, and after reading this bit in the documentation for the Rails extension of the class, it also seems potentially dangerous:
DateTimes aren’t aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zone
There's also this, in the Rails documentation for DateTime#to_time:
Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class. If self has an offset other than 0, self will just be returned unaltered, since there’s no clean way to map it to a Time.
I assume that last part is due to DateTime not recognizing DST.
It seems to me we have this:
The Date class represents a simple date without a time.
The Time class represents a specific point in time, which implicitly includes the date.
The DateTime class is the same as the Time class, but doesn't understand DST and sometimes can't convert to a regular Time class.
So should DateTime just be banished from the code base or does it serve a useful purpose which I am missing?
DateTime had an advantage over Time on 32 bit machines in Rubies < 1.9.2 - Time was a victim of the Y2K38 problem and limited to a 32 bit range. This problem is solved either on 64 bit machines and/or in recent Ruby versions. You still may need to use DateTime if for example 1.8 compatibility is a must or you rely on using methods from its API which often deviates from that of Time.
Related
Given rails has a convention for most common tasks, is there a format of date/time data that ruby/rails ingests most easily, or which it 'prefers'?
I will have date/time data coming from an external source, and I can choose how it's formatted (but it not be easy to change later). I have researched and found two recommended formats:
A string of format YYYY-MM-DD HH:MM:SS
Unix epoch time (i.e. number of seconds since 1 Jan 1970)
Does rails deal more easily with one of these formats over the other (or is there another convention?)
Additional note: I can see from this talk that it's almost always best to store time in UTC, so I have that much figured out
I would agree that Ruby on Rails default to using the UTC time zone at least in the database.
I do not see a strong convention what time string format Rails prefers, but I would always choose ISO 8601: 'YYYY-MM-DDTHH:MM:SSZ'
I am using ASP.NET Web Api 2 with Json.NET 6.0.1.
According to ISO 8601, dates should be interchanged in a certain way. I am using the IsoDateTimeConverter() in order to achieve this:
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter());
But how should "time of day" be returned in a JSON response model?
I cannot find anything for this in the ISO specification.
Should time perhaps be returned as a:
TimeSpan? (with expectation of the user to not use this as a duration representation)
DateTime? (with expectation of the user to drop off the date part)
A custom Time class
There is no standard structure in JSON for containing dates or times (see JSON.org). The de-facto stardard for dates-time values is using a string in ISO 8601 format, as you mentioned. But since there is no official standard it really comes down to what works best for you and consumers of your API.
Using a DateTime object is a reasonable choice because the support already exists in Json.Net and other serializers for converting these to and from ISO 8601 strings. So this would be the easiest to implement. However, users of your API would have to know to disregard the date portion, as you said. You could set the date to 0001-01-01 to emphasize its irrelevance. This isn't so different from the more common situation where you need only a date in your API and the time doesn't matter. Most people just set the time to midnight in this case and let it go. But, I would agree that this approach does seem to have a little bit of a "code smell" to it, given that part of the value is just noise.
Perhaps a cleaner idea is to format your DateTime value as ISO 8601, but then chop off the date portion before returning it. So users of the API would get a string that looks like 14:35:28.906Z. You could write a simple JsonConverter to handle this for you during serialization. This would sort of give you the best of both worlds -- a cleaner API, but you still can work with the familiar DateTime struct internally.
A custom Time class could also work here, but might be overkill, depending. If you do need to go there, you might want to look into a third-party library such as Noda Time, which has classes already built for these kinds of things, and also has pre-built converters for Json.Net.
I would definitely not choose TimeSpan for this purpose. Wrong tool for the job.
What is the standard way to present the ambiguous extra hour when winter time begins?
So far i used localized time formats to display and parse dates and times. E.g. 1. January 2014, 15:27.
I'm using location based time zones like "Europe/Berlin".
And i can't just change to plain GMT offsets because i do need to perform calculations on the dates. Otherwise i would get the wrong absolute time when moving across DST change dates.
All this works fine except for the one hour at the end of DST (e.g. October 26th 2014, 2am-3am) which occurs twice. I need to present it in a way that i can later parse again.
Is there a stadardized format? Do i just add a custom symbol? Do i use the GMT offset additionally to the geographic time zone? And how do i know when to use this special format - because i don't want to print it all the time, since it's redundant most of the year.
The answer by Matt Johnson is correct and insightful.
Java 8 & java.time.*
Let me add another to his list, from the new java.time.* classes bundled with Java 8 and defined by JSR 310. These new classes are inspired by Joda-Time but are re-architected.
The default used by java.time.ZonedDateTime is one concatenated string using square brackets around the time zone name and no spaces.
2014-10-26T13:49:48.278+01:00[Europe/Berlin]
#MattJohnson Feel free to merge this answer's content with yours if you wish.
There isn't a standard that combines everything. The closest you can get is with two fields. One which would be an ISO8601/RFC3339 Date+Time+Offset, and another which would be the IANA/Olson time zone.
Depending on your platform, you may have a single object that represents both, such as a DateTime in Joda-Time or a ZonedDateTime in Noda Time. But there is no standardized representation of this as a string.
Here are some that I have seen though:
Two completely separate strings:
"2014-10-26T02:00:00+01:00"
"Europe/Berlin"
One concatenated string, space separated:
"2014-10-26T02:00:00+01:00 Europe/Berlin"
One concatenated string with a space and using parentheses:
"2014-10-26T02:00:00+01:00 (Europe/Berlin)"
One concatenated string without any space, but with square brackets: (thanks Basil)
"2014-10-26T02:00:00+01:00[Europe/Berlin]"
As JSON, with some predetermined field names:
{
value: "2014-10-26T02:00:00+01:00",
zone: "Europe/Berlin"
}
As XML, with some predetermined attribute names:
<TimeStamp Value="2014-10-26T02:00:00+01:00" Zone="Europe/Berlin" />
As XML, with some predetermined element names:
<TimeStamp>
<Value>2014-10-26T02:00:00+01:00</Value>
<Zone>Europe/Berlin</Zone/>
</TimeStamp>
Any of these would be acceptable. Pick the one that fits your situation, or adapt to something similar.
Regarding your question:
... how do i know when to use this special format ...
When you're recording an event that has already passed and cannot be changed, then you do not need to store the time zone. The date+time+offset value alone is sufficient. Otherwise, you need both.
In my application I am reading from one database and writing to a second. The app is quick and dirty so I am reading / writing using AsString on both the FieldByName and ParamByName of the queries.
This works for all my use cases apart from where the data type is Date or DateTime
As far as I can tell FieldByName.AsString uses the system ShortDateTime format to return dates as (in my case) dd/mm/yyyy. The database expects the date to be written in as yyyy-mm-dd
According to Delphi Basics I should be able to set ShortDateFormat to what I need, but it appears that in XE5 this is no longer the case (correct?)
Further digging on here returns these two questions that use TFormatSettings to override the local settings. However, both of these use the resulting FormatSettings in StrToDate and FormatDateTime directly.
So two questions
1) Can I tell my application to override the System ShortDateFormat?
2) If so, How (I have a Plan B if not)?
The use of a global variable for the date and time formats was a mistake committed long ago by the original RTL designers. Functions that rely on the global format settings, like the single parameter StrToDate are retained for backwards compatibility, but you should not be using them.
For conversions between date/time and string you should:
Initialise a TFormatSettings instance with your date format.
Call the two parameter StrToDate, passing your TFormatSettings to convert from a string to a date.
Call FormatDateTime overload that accepts a TFormatSettings when converting in the other direction.
Now, to the main thrust of your question. You should not be using strings at all for your dates and times in the scenario you describe. Use AsDateTime rather than AsString. If you happen to have a database column that does store a date/time as a string, then you'll should use the TFormatSettings based conversion functions to work around that design fault.
If you are absolutely dead set on doing this all with strings, and I cannot persuade you otherwise, then you need to use FormatSettings.ShortDateFormat from SysUtils to control your short date formatting.
I have an application which save datetime using Time.now, but when I retrieves it and compare with Time.now again it not the same format and result in unexpected result.
What should I do to always make this time standard all the time.
Thanks,
Rails treats time in a special way because time zone support in Ruby was deemed insufficient, i.e. Ruby Time instances only work with UTC and ENV['TZ'] A Time object persisted in ActiveRecord will therefore look quite different to the return value of Time.now. To get on the same page as Rails use Time.zone.now
Favorite thing ever when it comes to time parsing and standardizing values is the Chronic gem. Natural format time parser. Very handy. Saves me from a lot of work trying to write/read time formats correctly for databasing time formats. Maybe not really the solution to the problem, but its worth a look.