I've got a problem with timestamps between java and javascript.
I already found these 2 questions about the timestamps and I know about the timechanges all over the years.
Timestamp deviation Java vs Javascript for old dates (3600secs)
Why is subtracting these two times (in 1927) giving a strange result?
Basically at midnight at the end of 1927, the clocks went back 5
minutes and 52 seconds. So "1927-12-31 23:54:08" actually happened
twice, and it looks like Java is parsing it as the later possible
instant for that local date/time.
What the problems makes is that when I have javascript and put the timestamp in there then I get an other date than the Java date. I need this to show the correct date on the webpage. I know I can request the date as a string but I prefer using a timestamp.
Java date 0001-01-01 timestamp is -62135773200000
JavaScript date 0001-01-01 timestamp is -62135596800000
The difference is -176400000; 49 hours.
Does anybody know what I can do for this.
Personally, I would avoid passing numerical timestamps around from a system in one language to a system in another language for the sole reason that the languages may differ in the algorithm they use to generate them.
There is an international standard in place (ISO-8601) to deal with passing timestamps from system to system. In this your date representation becomes 0001-01-01T00:00:00+00:00. I would recommend using this approach, as it's a widely accepted solution for this very problem.
This might be related to TZ and DST settings which diverge from browser to java. In order to nail it down, I recommend to use ISO-8601 formats like 2008-02-01T09:00:22+05, this is ambiguous-less
Related
One of our programmers decided to use a DATE field in the MySQL db in order to achieve this.
Sending and saving a JS date object did work well until the daylight saving changes intervened (with nasty effects :) ).
Of course, saving the date in a DATETIME field solves it, but everybody sees the time/dates in their own timezone.
We need everybody (all over the timezones) to see the same date!
I clarify this, to get the proper answers:
I want to keep using the DATE field storage type in MySQL (vs DATETIME - ok, maybe too much of an optimization, but it's already there and I want a long term solution for when I receive such structure/code from other developers)
Sending local time (local JS in browser) 23-05-2016, will reach the server as 22-05-2016 0X:X0:00Z (UTC) and be store as such. Because it's a DATE field, the stored value will become 22-05-2016 only. And you lost a day! :)
Our solution from bellow not only fixes the DATE field trimming, but also adds the fact that people now can see the same correct date (23-05-2016) no matter of the timezone they are in!
I like the outcome and would love to see some better solutions to achieve the same and improve the system.
Actually, we have noticed the problem only when the daylight saving time changed, so my solution (as answer bellow) is a good solution for that as well. And it only consumes resources client-side.
I have posted my own solution to this question as an answer bellow.
It would be really cool to see a much better solution from you!
With Javascript
Save your dates in ISO format (including timezone information) and use moment.js to convert the datetime to another timezone.
If moment.js is not already a dependency, and you want to avoid extra libraries, keep reading.
With MySQL
Instead of solving this problem when you write the data (losing timezone information in the process), solve it when you read the database.
In your SELECT query, normalize all DATETIME values to your preferred timezone using the convert_tz built-in function.
MomentJs is your best bet. Find the timezone you want and pass the ISO string to it and you should be good to go.
http://momentjs.com/timezone/docs/#/using-timezones/
A DATE is just a year, month, and day. It doesn't have a time, or a time zone. Think about your birthday or your wedding date, or today's date.
The JS Date object is not this at all. It's a timestamp. It's the number of milliseconds elapsed since Midnight January 1st 1970 UTC.
You should leave your date as a date-only wherever possible. Use the ISO-8601 date-only format, which is YYYY-MM-DD. If you have to assign it a time and time zone, then be very careful when you do.
If you just assign midnight local time, then you're risking losing a day (as you showed), and you're not considering that there are local days in some time zones where midnight does not exist! (Such as the spring-forward day in Brazil). Noon is a safer bet than Midnight, but still you should use this sparingly. The better approach is to keep dates as dates, not as date-times.
Also, I'd answer with code if I could, but you didn't provide any code in your question showing what was broken. Please read How do I ask a good question? and How to create a Minimal, Complete, and Verifiable example. Thanks.
There are more solutions to this, but the fastest and easiest that I could come up with is described bellow:
Let's intervene as early as possible in the information stream.
Just change the data before transmitting it through AJAX.
The function we used is this:
function addTimezoneDiffAnd12HoursToDate(date) {
var timezoneOffset = date.getTimezoneOffset();
date.setHours(12-Math.floor(timezoneOffset/60));
date.setMinutes(-timezoneOffset % 60);
return date;
}
What it does is that it converts a Date to be always at noon (12:00) UTC!
You can use it like this:
$scope.contract.contractDate = addTimezoneDiffAnd12HoursToDate($scope.contract.contractDate);
and send it as such to be stored in the DATE field.
Let me know if you have a simpler solution. I'd like to see it.
I'm using FormatJS library along with Handlebars to display a list of events that occured in the past. I'm calling for an endpoint on my server's REST API which returns me the list of events in Json, with datetimes to display for each event. ATM I'm saving datetimes in the DB using GMT time zone.
So when I'm getting my Json, I'm handling datetimes like this :
{{formatRelative commentDate}}
My issue is, since the datetimes are stocked in GMT, they display also like that. For example, since I'm on a GMT+2 timezone, as soon as a new event is created and shows up on the list, I see it "happened 2 hours ago" while it should be "a few seconds ago".
So, is there a way I can handle this ? Am I making a mistake in saving datetimes in GMT in my DB, and if so, how would you handle datetimes coming from different timezones and displaying them to people in other timezones ?
Of course I could customize the formatRelative helper to play with getTimezoneOffset and get the wanted result, but I wanted to know if there is something better to do.
Thanks a lot ahead !
The key to understanding your question is what you wrote in the comments:
Getting the Json, containing datetimes in the format 2016-02-28 10:15:53 - that's UTC time
You should ensure the value in JSON is in full ISO8601 format, including the appropriate offset or Z character to indicate UTC: 2016-02-28T10:15:53Z
Without the offset, most implementations will consider the value to be represented in local time, which explains your results.
Thus, the problem is with your server-side code, not your JavaScript code. There may be a client-side workaround you could apply when the date string is parsed from JSON, but really the best solution would be to qualify it at the server.
I have seen and read a number of comments regarding calculating the days between dates, as it relates to JS. My question is-I need to calculate this information in Adobe LiveCycle Designer. I have the two fields I need to reference in the script. The first is the static field with the last known date of an event, the second is the current date/time (which is entered by the end user). I need to know how to write the script to find the difference between these two fields, with the calculation resulting in days. I do not need to be exact, daylight savings time, leap year, time zones etc. are not important. Just need to get to an integer. Thanks in advance for the help.
The quick and dirty way to do it involves an epoch subtraction. In Javascript, the date epoch is available from Date.getTime(); as seen on W3 Schools. If you're looking for a more robust approach and if you have a need for additional date and time operation, I would suggest looking into Moment.js. Moment.js is technically a JavaScript library aimed at browsers, etc. but it can be wrapped in a Script Object to be used in an XFA form.
I have a jQuery app that sends a date object to python for parsing. The problem is that when I try to use my jQuery on the Windows machine, the date object looks like this:
Tue Mar 12 2013 00:00:00 GMT-0600(Mountain Daylight Time)
Whereas on my Mac, I get:
Tue Mar 12 2013 00:00:00 GMT-0600(PST)
When I try to parse these in Python with the strptime function, it fails because it doesn't understand the time zones on the end of the first (the MDT one). It complains that is an "unknown string format".
How do I resolve this? Am I doing something wrong?
The best solution here is probably to have your jQuery code convert its datetimes to GMT before sending them. (If you want the timezone as well, send it separately.) Then you can get them out of the JSON (or whatever) on the Python side, turn them into GMT datetime objects with strptime, and use them, and you're done.
But the simplest solution,* with the least code change, is to just let jQuery do the wrong thing and throw away the timezone on the Python side. Basically, instead of this:
dt = datetime.datetime.strptime(jsondate)
do this:
dt = datetime.datetime.strptime(jsondate.partition('(')[0])
Notice that throwing away everything after the '(' still leaves you with the -0600 part; you're just losing the "PST" or "Mountain Daylight Time" part.
And those parts were not doing you any good anyway. datetime doesn't understand these timezone names. And, even if it did, it has nothing to map them to except for offsets (which you already have). If you want real timezones, you need some third-party library like pytz.**
On top of that, strptime specifically returns naive datetime objects, not aware ones. So, even if datetime could parse and look up the timezones, it still wouldn't do anything useful with them, unless you parsed the datetime, then pulled out the timezone and parsed it separately and looked it up and then called astimezon on the datetime.
So, in summary, the worst-case scenario for throwing this information away is exactly what you already have.
As a side note, on three projects in a row, I pushed a datetime serializer into my JSON en/decoder on the Python side (and a matching serializer on the JS side, for the one that had a JS side) specifically so I could pass a UTC datetime (in ISO8601 format, because that's as easy to use for computers as a seconds-since-epoch, and a lot easier to read/edit for humans) and a timezone offset today, but switch to a tzinfo key if it because important later. All three times, it never became important… And the projects where it has been important, I've usually been passing around ICAL schedules or pre-Gregorian dates or other similarly fun stuff.
Finally, as someone who's written way too much date-related code over my career, I have to say this: If you know of any evil overlords planning to take over the world, if they promise to abolish timezones, I am willing to overlook their other programs of enslaving humanity or making kittens fight babies and sign up as a henchman.
* … at least simplest for me, since I know Python a lot better than JS and jQuery. :)
** IIRC, pytz can't handle NT-style timezone keys like "Mountain Daylight Time" either, so you actually need yet another library to handle that. I think I got that out of a library that did all kinds of MS datetime stuff, including handling the differences between Microsoft's three similar 1601-ish epoch times (two not-quite-the-same epochs, different rules for special "end of time" and "start of time" and "not a date" values, …).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a standard date/time format that can be passed on a URL?
What is a good way for a RESTful resource to accept a datetime object? Specifically, I'm not sure what is a good way to represent the date and time as a query argument in the URL.
I was thinking of doing something like this:
GET /Calls?start=YYYY-MM-DD_HH:MM:SS
I'm using Javascript/jQuery on the Client and Python on the back end, so ideally it would be a format that could easily be written in Javascript and read in Python.
Thanks!
Use the ISO 8601 standard to encode the time argument as a string. It's readable for humans and supported by tons of libraries across many languages.
I'd recommend against using Unix time. Your sysadmins will thank you when they're asked to crawl or parse your web server logs for API calls. Using ISO 8601 will avoid them having to build a secondary step into that process to convert the Unix time number into something that actual humans have to understand.
Most datetime libraries (definitely both Python and JS) follow the same formatting approach, namely format strings. I'd go with any one that just uses digits, and uses descending order of size, i.e. YYYYMMDDhhmmss.
The one other thing to consider before jumping into a format is whether you might need to parameterize by something more akin to a date range, and if including the seconds, minutes, hours, etc. might over-specify the request and make it hard for the client to locate the data they are looking for.
unix time... http://en.wikipedia.org/wiki/Unix_time
why not just YYYYMMDDHHMMSS ?
As long as both sides can follow this format, I don't see any problem