I have case classes that may be used for representing models that originate from either a database table or API object.
Should I use joda or java.util.date or java.sql.date or?
This is for a playframework app, and I will use these models to display the datetime on the UI side of things where I will convert the date to the current users timezone also.
I'm just really confused.
Agreeing with the Answer by mkurz…
java.time
Both java.util.Date and java.sql.Date, and their related classes, have been supplanted by the java.time framework built into Java 8 and later. See Oracle Tutorial. Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
Search Stack Overflow to learn more (after reading the Oracle Tutorial linked above). Many examples and discussions have been posted.
Basic concepts
Date-time handling is surprisingly tricky. Leave your intuition at the door.
Strings are not date-time values; they are a representation of date-time values. Focus on using objects, not strings.
You may work with a date-only, a time-only, or a date-time.
Know that offset-from-UTC is just a number of hours/minutes/seconds while a time zone is a superset, adding rules for handling anomalies such as Daylight Saving Time (DST). Use OffsetDateTime for one, and ZonedDateTime for the other.
ISO 8601 standard provides sensible formats when parsing & generating Strings to represent date-time values.
The “Local…” types mean “no specific locality”. These have no meaning, are not points on the timeline, until you specify the context of a specific time zone.
The 3-4 letter abbreviations such as EST or IST you commonly see in the media are not time zones, are not standardized, and are not unique(!). Proper time zone names are continent/region.
Apply a time zone for presentation to the user, but most of your business logic, data storage, and data exchange should be in UTC (the Instant class).
Tips
While programming, forget about your own local time zone. Think in UTC.
Learn to read & write 24-hour clock times.
I would recommend http://www.joda.org/joda-time/quickstart.html
It works really nicely with play's json formatters and comes with a ton of helpers.
You are looking for java.time.ZonedDateTime which was introduced in Java 8 and should be used for representing date and time related information that have a timezone. You can save values like 2016-05-30T00:23:27.070Z with it. There is no need to use a third party library like joda time anymore (maybe in other cases there is, but not in your's)
(Do not use java.util.Date - most of it's methods are deprecated, for good reasons)
As a blogger saied:
「Scala does not have a datetime package, but we can use the ones provided by Java.
Java 8 provides a better data/time API, so 3rd-party libraries like Joda-Time is no longer required.」
Here is the blog:
https://www.hackingnote.com/en/scala/datetime
This will be helpful to you.
Related
Discussing data time-formats, someone mentioned to me how he stores datetime (in a human-readable format) using floats as yyyymmdd.hhmmss, so 2019-09-18, 11:29:30am would become 20190918.112930
I'm trying to find out if this guy has invented his own format or if it is used (and described) elsewhere too - and if so, how is it even called...?
It’s probably homespun
I have seen a lot of date and time formats, and I have not seen this one before. My go is that his guy or his organization invented it themselves.
Edit: Thank you for confirming in the comment. Since comments are not always permanent on Stack Overflow, I quote here, you said:
Finally got confirmation from the source: it's homespun indeed.
As an aside I don’t like it. A float is stored in a binary format internally, and only after formatting it into decimal does it become human readable. Using a float for a “human readable” date and time was not what formatting of floating-point numbers was meant for, it’s a hack.
Use ISO 8601
For a human-readable format I recommend ISO 8601. Here 2019-09-18, 11:29:30am becomes 2019-09-18T11:29:30. Or even better and still within ISO 8601, convert to UTC and append a Z to denote UTC. So if your original time was in Europe/Berlin time zone, it would become 2019-09-18T09:29:30Z. As you can see, ISO 8601 is even more human readable than you friend’s format, and it is sortable as strings (as long as the years don’t go beyond 9999).
While he may have come up with it himself, it is also a formatting option in zipinfo.
The manual doesn't explicitly name it, but describes it as a sortable decimal format and decimal format.
Not sure if we are talking about SQL date format. If so, this date format is present in SQL Statements.
Not sure about the name, it's called in different ways: non-standard, ISO, Other format and so on.
Is present also in PHP.
According to Wikipedia, this would be similar to the ISO 8601, which permits, all of the following for date and time combined:
2019-09-18T09:18:26+00:00
2019-09-18T09:18:26Z
20190918T091826Z
except that the T to separate the time from the date is replaced by . and the time-zone information is dropped.
That specific format has limited popularity either in the yyyymmdd.HHMMSS or the C's strftime()-compatible %Y%m%d.%H%M%S form.
EDIT
As far as using float for date and time the way you suggests, it depends on the precision and machine representation.
If the system is following IEEE 754 basic standard (which is what most modern C compiler stick to), you would need at least float64.
However, it is not common to do so.
This might be in part because it may be difficult to correctly predict the accuracy of the time information, and it is not as bit-efficient as the Unix time.
Given that the only positive feature it has is that it can rely on standard %f from sprintf(), I would only see it advantageous when strftime() is not available or a performance bottleneck.
As we aware that, in java we can use existing API's to get the current date and time, compare to that what is the difference between the new LocalDateTime class now() method.
tl;dr
If referring to Date, Calendar, and SimpleDateFormat, those are terrible old classes, now legacy. Never use.
Use only the modern java.time classes.
LocalDateTime cannot represent a moment, as it purposely lacks any concept of time zone or offset-from-UTC. So LocalDateTime.now is of no practical use.
Capture the current moment using Instant.now for UTC, or ZonedDateTime.now for a particular time zone.
Avoid legacy date-time classes
If by “existing API's” you meant the old date-time classes such as Date, Calendar, and SimpleDateFormat, you should avoid those. While they were well-intentioned industry-leading attempts at date-time handling, they proved to be poorly designed, confusing, and troublesome. They are now legacy.
Use java.time
Instead, use the java.time classes. Added to Java 8 and later. Much of the functionality was back-ported to Java 6 & 7 & Android as well.
Local… types
The “Local…” classes lack any concept of offset-from-UTC or time zone. As such, they are only a vague idea about possible moments. Without an offset or zone the have no real meaning.
An example of a local date-time is when Christmas begins, 2016-12-25T00:00:00. That does not determine a specific point on the timeline until we apply an offset or zone. Christmas starts earlier in the east. That is why Santa starts his deliveries in the Pacific such as midnight in Auckland NZ and works his way towards Asia with its later midnight, then flies the reindeer on to India after its midnight begins later, and so on westwards.
LocalDateTime not often used
So while there might be use-cases for calling now on LocalDateTime, I cannot imagine one.
The main use for LocalDateTime is in parsing strings that lack any indication of offset or zone. Such strings are poorly designed as they are incomplete. Would you communicate a price without specifying the currency? So too it is unwise to specify a date and a time but no offset/zone. At any rate, when you do have such strings lacking offset/zone, parse with LocalDateTime.
LocalDateTime ldt = LocalDateTime.parse( "2016-01-23T12:34:56.789" );
If you know the intended offset because of your given scenario, apply it.
ZoneOffset offset = ZoneOffset.ofHours( -7 );
OffsetDateTime odt = ldt.atOffset( offset ); // Now we have a moment, a specific point on the timeline.
Better yet, if you know the time zone because of your given scenario use that instead of an offset. A zone is an offset plus the set of rules for handling anomalies such as Daylight Saving Time (DST).
ZoneId zone = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ldt.atZone( zone ); // Now we have a moment, a specific point on the timeline.
In common business apps we tend to care about precise moments: When did the invoice arrive, When does the contract expire, Appointment start time, and such. For such point-on-the-timeline values, we use Instant, OffsetDateTime, and ZonedDateTime. Search Stack Overflow for many examples and more discussion. Each of these offer a now method. Calling their now method retains the important offset/zone info while capturing the current moment. In contrast, calling LocalDateTime.now discards that offset/zone info intentionally, rarely what you want.
Tip: Always pass the optional offset or zone argument to now.If omitted you are relying implicitly on the JVM’s current default time zone being applied. This default can be changed at any moment during runtime by any code on any app within that JVM. Better to specify explicitly your desired/expected offset or zone. IMHO, that optional argument should have been required to remind programmers that they must be always be consciously aware of time zone.
Current moment
Capture the current moment in UTC using Instant.
May be captured in a resolution as fine as nanoseconds but more likely microseconds or milliseconds depending on limitations of your JVM implementation, your host hardware clock, and your host OS.
Instant instant = Instant.now() ; // Capture current moment in UTC.
Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Or, as a shortcut, skip the Instant part.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
If the zone argument is omitted, the JVM’s current default time zone is applied implicitly. Better to specify your desired/expected time zone.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I have to delete a few tests I create if the timestamp on these are older than a week.
On making a call to the API I get the created_at time stamps of all the tests in this format :
2014-08-04T04:49:28Z ,
2014-08-04T04:49:22Z ,
etc..
It looks like a DateTime object but is a String actually. So firstly is there a way to convert this to a DateTime object?
I need to compare these against the current time and date and check whether they are older than a week or not. For this I know there are several ways but I wanted to know which one is the shortest and most efficient in scala without importing any java utility. Though Joda would have been helpful but the API response gives me String
Thanks in advance!
Consider Scala wrappers for Joda (e.g GitHub /nscala-time
). It provides a rich API and avoids Java Date non thread-safety and mutability.
See What's the standard way to work with dates and times in Scala? Should I use Java types or there are native Scala alternatives? for further comments/discusison and usage examples.
What is the best way to transfer Dates and Times across. I am using GWT on the client/browser side and .NET C Sharp on the server and I am using JSON as data-interchange format. I am currently storing all the dates and times on the server as .NET DateTime. Now I have noticed, that if I use the GWT DatePicker or DateBox to pick a date and send it to the server as miliseconds (by doing date.getTime()) where the server takes this param as DateTime, I can see an hour offset due to the BST. I have situations where I have to have the date and time in separate boxes on the UI and the time setting along with the correct date is crucial because of scheduling.
The best way to interchange Date and Time values would be to serialize them into culture-independent, UTC based strings like: 2010-09-18T18:37:11. The problem is, Date and Time related operations tend to be implemented incorrectly...
As for your problem, I assume that it pops up during deserialization of JSON time, i.e. .Net treats this time as local (DateTimeKind.Local or DateTimeKind.Unspecified), thus converting it. Not sure how to deal with it, the brute force would be probably sending serialized string like above and deserializing manually like this:
DateTime date = DateTime.Parse(dateString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
I'd recommend using standard such as ISO 8601 to transfer date time info in a string form. At my company, date time information encoded in JSON object is almost always in this format, e.g. "2015-10-12T18:41:11+01:00". This string can be parsed and understood correctly in all clients with different programming languages (Obj-C, Java, C/C++).
I've been searching for a definitive answer to this, and the XML schema data types document seems to suggest that timezones are accepted, yet I found at least one implementation which does not properly convert time zones ( NUSOAP ).
To make sure that the problem is not at my end, I'd like to know if a format such as 2009-11-05T11:53:22+02:00 is indeed valid and should be parsed with timezone information, i.e. as 2009-11-05T13:53:22.
Given the following sentences from the w3c schema documentation:
"Local" or untimezoned times are
presumed to be the time in the
timezone of some unspecified locality
as prescribed by the appropriate legal
authority;
and
When a timezone is added to a UTC
dateTime, the result is the date and
time "in that timezone".
it does not sound like there is a definitive answer to this. I would assume that it is the usual ambiguity: Both versions are principally valid, and the question of what version to use depends on the configuration/behavior/expectations of the system one is interfacing with.
And even if there where a definitive answer, I would definitely not rely on it, but rather expect that every other web service and library had its own way of dealing with this :/
You converted the timezone incorrectly.
2009-11-05T11:53:22+02:00
is equivalent to
2009-11-05T09:53:22Z
Is that what NUSOAP did?