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.
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'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
I need a way to serialize and unserialize dates that are potentially far away in the past, for instance -10000
I first look at ISO8601, but it does not seem to support years with more than four digits. (Or at least, python libraries I tried don't.)
The different solutions I can think of:
change the year before serializing/deserializing, give it to the parsing/formatting library, and fix it back (sounds hacky)
define my own format, like year:month:day:hour:minute:second (that is reinventing the wheel, since I have to handle timezones, etc.)
Use a UNIX timestamp without bounds or something equivalent (may overflow in some programming languages, and still the timezone stuff)
Store dates before -9999 (or 0) differently than those after, since there was no timezone issue/leap years/… issue at that time. (two different formats at the same place)
Do you see any other way that would be better than these ones? Or recommand one of those?
You could take a page from the astronomy people. Sky maps they account for long period precession of Earth's spin by establishing epochs. (The sky is different if you're looking now vs 10,000 BC.)
Create a new class that has an "epoch" number and a facade pattern of your current date class. The new class contains two private fields for epoch and internal-date. Your constructor sets epoch to (year div 10000), and instantiates the internal-date with (year modulo 10000). I hope rest of the facade pattern is as obvious as I think.
ISO 8601 does support dates with more than 4 digits if, and only if, they are signed. The only PHP function I know of that supports this functionality is
DateTime::setISODate($Year, $WeekOffset, $DayofWeekOffset)
Obviously it's a pain to use because it requires calculating the offsets from perfectly good day/month pairs. That said, you should be able to create BC dates by signing the year with a '-'(minus sign).
Then you'd output the date with
DateTime::format("c")
In production this would look something like:
$date= new DateTime();
$date->setISODate(-100000,$WeekOffset, $DoWOs);
echo $date->format("c");
Take a look at FlexiDate class — it might be useful for you purposes.
It is not a standards-compliance way in any way, but it might do the trick for you
I came across this webpage in which the date of the article is an integer which is formatted by an inline call to a JavaScript function into the string "Nov 6, 2009 10:17am".
The markup looks like this
<small>
<script type="text/javascript">timestamp(1257520620000,'longDateTime')</script>
</small>
Is there a good reason to deal with dates in this way? I'm having a hard time thinking of one.
The best idea I can come up with is they would display in the correct time zone and local format for the visitor.
This may be to deal with times zones and the effect of changes to time for day light saving, so the time is stored as some UTC or Unix time, e.g. a number of seconds/milliseconds since and known starting point. Then rendered for each user based on their location.
This is fairly common on international applications.
I think they want to hide the date from news crawlers
I have set a deadline in UTC, as shown below, and I'm wondering what exactly the toLocaleString() method will do to it on user's local machines. For instance, will it account for daylight savings if they are in a timezone that recognizes it? Or will I need to insert additional code that checks where the user is, and then fixes the displayed time?
http://javascript.about.com/library/bldst.htm
var deadline = new Date('5/1/2013 ' + "16:15" + ' UTC');
alert(deadline.toLocaleString());
In general, the answer is yes. JavaScript will represent the UTC value at the appropriate local time based on the time zone settings of the computer it is running on. This includes adjustment for DST. However, as others have pointed out, the details are implementation specific.
If you want a consistent output, I would use a library to format your dates instead of relying on the default implementation. The best library (IMHO) for this is moment.js. The live examples on their main page will give you an idea of what it can do.
UPDATE
If you are passing UTC values that you want converted to the correct local time, and that time falls into a period where the time zone rules are different than the current one - then the results will be invalid. This is crazy, but true - and by design in the ECMA spec. Read - JavaScript Time Zone is wrong for past Daylight Saving Time transition rules
We don't know what exactly the toLocaleString method does (§15.9.5.5):
This function returns a String value. The contents of the String are
implementation-dependent, but are intended to represent the Date in
the current time zone in a convenient, human-readable form that
corresponds to the conventions of the host environment’s current
locale.
But yes, most implementations will consider DST if it is active in the current local timezone. For your example I'm getting "Mittwoch, 1. Mai 2013 18:15:00" - CEST.
Will I need to insert additional code that checks where the user is, and then fixes the displayed time?
I think you can trust toLocaleString - the browser should respect the user's settings. If you want to do it manually, check out timezone.js.
As you use "UTC" the date itself will be UTC format, but the toLocaleString() takes client's locale into account, which means it'll return the date in string updated with all and every changes typical to client's regional and locale settings (DST, date/time format, etc).As JS documentation describes this: "The toLocaleString() method converts a Date object to a string, using locale settings.".If you want to avoid this, use the toUTCString() method instead.I'd also recommend reading the accepted solution for the question Javascript dates: what is the best way to deal with Daylight Savings Time? to avoid (at least, to try to avoid :) future issues related to JS, browsers and locales.Hope this helps!