JXA: Number gets changed when passed as parameter to library module? - javascript-automation

I am trying to pass a number (date in ms) to a function in a library module. The number gets screwed up!
Here is a simple look (function MailUtils.showNum has only one line, the same log call as seen below):
n = Number(todayMs - mbRetMs);
Logger.logDebug("Num = " + n + "; as Date = " + new Date(n));
MailUtils.showNum(n);
Log:
/* Num = 1500396760628; as Date = Tue Jul 18 2017 12:52:40 GMT-0400 (EDT) */
/* Num = 1453174324; as Date = Sat Jan 17 1970 14:39:34 GMT-0500 (EST) */
Seriously ???
What the * is happening? Looks like it somehow figures out it is a date and passes the origin date (the date the ms are counted from)?

LOL, Int32 Overflow #Fail. What you’re seeing is your original [64-bit] integer's 32 Least Significant Bits; the high bits have all been stripped.
Odd in itself, since JS uses Double internally; presumably a bug in JXA. (It has a lot of those.)
If you like JavaScript I strongly recommend using Node.js instead. JXA is rubbish in comparison, and with OSA technologies now in maintenance mode I don’t imagine it’ll ever get fixed.

Related

chrome 67 date vs Chrome 66 date

The code is:
var rightNow = new Date();
console.log(rightNow);
In Chrome 66 it returns:
Tue Jun 12 2018 15:36:19 GMT+0530 (IST)
In Chrome 67 it returns:
Tue Jun 12 2018 15:36:43 GMT+0530 (India Standard Time)
Why the difference?
A lot of my code works with the behaviour in chrome 66. Do I need to change all the code?
In general, you should not code for a specific browser, but to the standards. In this case, the standard is ECMAScript (ECMA-262). Section 20.3.4.41 covers Date.prototype.toString(), which refers to the following section describing the internal ToDateString(tv) function, which explains:
Return an implementation-dependent String value that represents tv as a date and time in the current time zone using a convenient, human-readable form.
By "implementation-dependent", it means that the actual string value is not defined by the specification, and can vary from one implementation to another. You are not guaranteed the same result from one browser to the next, or from one version of a browser to the next, or even from one operating system to the next from the same version of the same browser.
By "human-readable form", it means that the value produced is suitable for display to a human being. It makes no guarantees about that value being represented in a manner that can be parsed consistently by computer code.
Thus, if you intend for the string value to be sent to other code, you should not use .toString(). In general, you should prefer an ISO 8601 formatted string for this purpose. Use .toISOString() if you want the result in terms of UTC. Refer to this answer (or use a library) if you want the result in terms of local time including a time zone offset.
As to why things changed between Chrome 66 and Chrome 67 - I don't have the exact details, but I assume Chrome switched from using IANA TZDB abbreviations to using CLDR time zone names, probably through its use of ICU. This is reasonable, and is what many other implementations are doing. There's no requirement it use one set of data or the other though, so don't rely on such things.

Time difference between chrome / edge on windows 10

I get TZ difference on windows 10 between Chrome and Edge.
When I run this code in the console:
> var date = new Date(2013, 2, 29, 1, 0, 0, 0);
> date
This will be the output when running in on Edge
> [date] Fri Mar 29 2013 01:00:00 GMT+0200 (Jerusalem Standard Time)
While This will be the output on Chrome:
> [date] Fri Mar 29 2013 01:00:00 GMT+0300 (Jerusalem Daylight Time)
It seems that in Chrome it is recognise as DST but in Edge it doesn’t, which is correct.
(Attached screenshot)
If I turn off the “Adjust for day light saving time automatically” configuration - Chrome date becomes the same. (image2)
Someone, can explain why? and how to get the correct TZ in chrome in any "Date and Time" configuration?
Edge version: 20.10240.16384.0
Chrome version: 56.0.2924.75 (64-bit)
This indeed appears to be a bug.
The TZ Database shows:
# As of 2013, DST starts at 02:00 on the Friday before the last Sunday
# in March. DST ends at 02:00 on the last Sunday of October.
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Zion 2013 max - Mar Fri>=23 2:00 1:00 D
Rule Zion 2013 max - Oct lastSun 2:00 0 S
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Jerusalem 2:20:54 - LMT 1880
2:20:40 - JMT 1918 # Jerusalem Mean Time?
2:00 Zion I%sT
Therefore, in 2013, DST should have started on the Friday before the last Sunday in March, which was March 29. (The previous Friday was March 22, which doesn't meet the Fri>=23 rule in the time zone data.) This is date is also corroborated by timeanddate.com.
Windows appears to have this data correct. Examining the registry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Israel Standard Time\Dynamic DST
The last part I highlighted in green is the DST start date.
00 00 = Year (ignored)
03 00 = Month (March)
05 00 = Day of week (Friday)
05 00 = Day number (5 = last)
02 00 = Hour (02:00)
00 00 = Minute
00 00 = Second
00 00 = Millisecond
So both the Windows and the IANA data are pointing at the same date. Yet somehow Chrome is getting it wrong.
I also tested FireFox, which also appears to be getting it wrong:
I can also reproduce these results in Node.js.
But yes, Edge is getting it correct:
Do note that the browsers also differ in which direction they adjust a local time that falls into the "gap" created by the spring-forward transition. This is expected, and is being worked on in for a future version the of ECMAScript spec.
I don't work on the actual implementation within these browsers, but my understanding is that both Chrome, Node, and FireFox rely on ICU for their time zone internals. My guess is that it is an ICU bug that is being exposed here. Update: It appears to be a bug in the Microsoft C/C++ Runtime. I'm working on getting it to the right folks.
As far as what to do about it - if accurate historical time zone data is essential to your application, I strongly suggest you not rely on the environment to provide it, but bring it yourself using one of the libraries I listed here, such as moment-timezone (which I help maintain).

Does the Google Directions API use UTC or Local Time?

I am developing a transit navigation app using the Google Directions API.
The API requires me to submit a departure time (departure_time) for transit queries.
Is it necessary to convert the local time to UTC time for this parameter?
I could not validate it through the API's response, as there is no accurate time returned in it.
That Doc Was In Error
Apparently the Google team writing that doc page made an error and later fixed it.
The number you report 1343605500 is no longer found on that page. Today the number on that page is 1343641500. I suspect you did indeed see that number on that page previously. Googling (ironically enough) for site:https://developers.google.com 1343605500 does list that page as a hit. Apparently the hit is based on a cached copy of the old erroneous page. Even Google cannot escape the reach of Google.
Work in UTC/GMT
Is it necessary to convert the local time to UTC time for this parameter?
Yes.
The API works with GMT/UTC (no time zone offset), which only makes sense when you think about it. Almost always, the best practice for handling date-time is to perform your business logic, serialization, database records, and so on in UTC, then convert to local time only for presentation to the user.
Just looking at the example URL itself suggests it is in UTC. The only possible reference to a local time zone would be the word "Brooklyn" which is certainly not a clear unique identifier for a time zone.
http://maps.googleapis.com/maps/api/directions/json?origin=Brooklyn&destination=Queens&sensor=false&departure_time=1343641500&mode=transit
And of course the doc says the API uses UTC/GMT:
the desired time of departure as seconds since midnight, January 1, 1970 UTC
Poor Writing
The confusion stems from the poor writing in that documentation page. They need to append a crucial "UTC" or "GMT" to that "9:45 am". Mentioning New York and 9:45 in the same breath implies local time, whereas that example is truly 5:45 in the morning local time in Brooklyn.
The below request searches for Transit Directions from Brooklyn, New York to Queens, New York. When requesting transit directions, be sure to specify either a departure_time or arrival_time.
Note that in this example the departure time is specified as July 30, 2012 at 09:45 am. Update the parameter to a point in the future before submitting the request.
Old Versus New Numbers
Old number: 1343605500 (reported in the answer by davidg, and by googling)
New number: 1343641500 (found 2013-12)
Number if they had actually meant 9:45 in New York: 1343655900.
Example Code
I don't do JavaScript. So instead, I present some Java code using the sophisticated Joda-Time 2.3 date-time handling library running in Java 7. I use both the old (erroneous) and new (correct) numbers to show the date-time in both UTC and New York time zones. Furthermore, I calculate the number of seconds since epoch would have been used to get to 9:45 am July 30 2012 in New York, to produce a third number of seconds.
The Google API uses seconds, while Joda-Time uses milliseconds, so I multiply or divide by a thousand.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
DateTimeZone timeZone_NewYork = DateTimeZone.forID( "America/New_York" );
// On this page:
// https://developers.google.com/maps/documentation/directions/#ExampleRequests
// …look for the following two paragraphs…
// --
// The below request searches for Transit Directions from Brooklyn, New York to Queens, New York. When requesting transit directions, be sure to specify either a departure_time or arrival_time.
// Note that in this example the departure time is specified as July 30, 2012 at 09:45 am. Update the parameter to a point in the future before submitting the request.
// --
// Below that text, find this URL:
// http://maps.googleapis.com/maps/api/directions/json?origin=Brooklyn&destination=Queens&sensor=false&departure_time=1343641500&mode=transit
// Extract that departure time of 1,343,641,500 seconds since the Unix Epoch of beginning of 1970 UTC.
// Apparently in the past that page erroneously used the number 1343605500 where today it uses 1343641500.
// Use the correct number found on that page today, 2013-12-25: 1343641500.
DateTime dateTimeInUtcWithNewNumber = new DateTime ( ( 1343641500L * 1000L ), DateTimeZone.UTC );
DateTime dateTimeInNewYorkWithNewNumber = dateTimeInUtcWithNewNumber.toDateTime( timeZone_NewYork );
System.out.println( "dateTimeInUtcWithNewNumber: " + dateTimeInUtcWithNewNumber );
System.out.println( "dateTimeInNewYorkWithNewNumber: " + dateTimeInNewYorkWithNewNumber );
// Use the old erroneous number previously found on that page: 1343605500.
DateTime dateTimeInUtcWithOldNumber = new DateTime ( ( 1343605500L * 1000L ), DateTimeZone.UTC );
DateTime dateTimeInNewYorkWithOldNumber = dateTimeInUtcWithOldNumber.toDateTime( timeZone_NewYork );
System.out.println( "dateTimeInUtcWithOldNumber: " + dateTimeInUtcWithOldNumber );
System.out.println( "dateTimeInNewYorkWithOldNumber: " + dateTimeInNewYorkWithOldNumber );
// Calculating the number that should have been used if the Google team had actually meant 9:45 AM local time in New York: 1343655900.
DateTime dateTimeInNewYork_2012_07_30_09_45 = new DateTime ( 2012, 7, 30, 9, 45, 0, timeZone_NewYork );
System.out.println( "dateTimeInNewYork_2012_07_30_09_45: " + dateTimeInNewYork_2012_07_30_09_45 );
System.out.println( "dateTimeInNewYork_2012_07_30_09_45 in seconds since Unix epoch: " + ( dateTimeInNewYork_2012_07_30_09_45.getMillis() / 1000L ) );
When run…
dateTimeInUtcWithNewNumber: 2012-07-30T09:45:00.000Z
dateTimeInNewYorkWithNewNumber: 2012-07-30T05:45:00.000-04:00
dateTimeInUtcWithOldNumber: 2012-07-29T23:45:00.000Z
dateTimeInNewYorkWithOldNumber: 2012-07-29T19:45:00.000-04:00
dateTimeInNewYork_2012_07_30_09_45: 2012-07-30T09:45:00.000-04:00
dateTimeInNewYork_2012_07_30_09_45 in seconds since Unix epoch: 1343655900

Data type compatibility in C to Mysql

I got one issue while implementing the Ctime() in C using MS VC++ 2008 for running the application.
By using the ctime I will get current time format as Sun Jan 09 14:38:09 2011. Is there any way to convert the above format as 2012-01-09 14:38:09 (in MYSQL). Is there any direct functions in C.
Any suggestion to do this?
You can convert your time_t to a struct tm with localtime() (or gmtime()), then use strftime() to format the date as you want.
Example:
char out[20];
time_t t0 = time(0);
struct tm *tm0 = localtime(t0);
strftime(out, sizeof out, "%Y-%m-%d %H:%M:%S", tm0);
If you need different time_t values for different database columns, create them.
Then convert to struct tm and format each one as above.
Example:
time_t t0 = time(0); /* now */
time_t t1 = t0 + 3600; /* 1 hour from now */
time_t t2 = t0 + 24*3600; /* 1 day (24 hours) from now */
posted from comments to enable OP to accept as answer
According to man ctime():
The asctime() and mktime() functions both take an argument
representing broken-down time which is a representation separated into
year, month, day, etc.
I guess you can use these other functions to do what you want.
In my opinion, the one and only way to handle this (or any other) mismatch is to store the raw value returned by time() in your table; and then to let any application (including yours) format that value into any arrangement it wants to show the user.
This approach offers three big wins:
It takes advantage of the universal, simple, and well-documented time_t format, meaning you can give the db away and be sure that anybody can interpret and handle it with no further work/documentation for you. struct tm and ctime-like formats are completely arbitrary, chosen by some poor midnight programmer thirty years ago.
You avoid the well-deserved scorn and anger directed at you by anybody who wants to implement internationalization in what used to be your code.
Most important: it stores time in a format that you or anybody else can sort/select on, which is not true of any others.
It's foundational, I believe, that your table be as widely understood as you can make it. You can meet this goal by storing raw, time_t values.
There isn't one in C. Use mktime (or mktime_r) and sprintf to create your own time format.

Calculate date from numeric value

The number 71867806 represents the present day, with the smallest unit of days.
Sorry guy's, caching owned me, it's actually milliseconds!
How can I
calculate the currente date from it?
(or) convert it into an Unix timestamp?
Solution shouldn't use language depending features.
Thanks!
This depends on:
What unit this number represents (days, seconds, milliseconds, ticks?)
When the starting date was
In general I would discourage you from trying to reinvent the wheel here, since you will have to handle every single exception in regards to dates yourself.
If it's truly an integer number of days, and the number you've given is for today (April 21, 2010, for me as I'm reading this), then the "zero day" (the epoch) was obviously enough 71867806 days ago. I can't quite imagine why somebody would pick that though -- it works out to roughly 196,763 years ago (~194,753 BC, if you prefer). That seems like a strange enough time to pick that I'm going to guess that there's more to this than what you've told us (perhaps more than you know about).
It seems to me the first thing to do is verify that the number does increase by one every 24 hours. If at all possible keep track of the exact time when it does increment.
First, you have only one point, and that's not quite enough. Get the number for "tomorrow" and see if that's 71867806+1. If it is, then you can safely bet that +1 means +1 day. If it's something like tomorrow-today = 24, then odds are +1 means +1 hour, and the logic to display days only shows you the "day" part. If it's something else check to see if it's near (24*60, which would be minutes), (24*60*60, which would be seconds), or (24*60*60*1000, which would be milliseconds).
Once you have an idea of what kind of units you are using, you can estimate how many years ago the "start" date of 0 was. See if that aligns with any of the common calendar systems located at http://en.wikipedia.org/wiki/List_of_calendars. Odds are that the calendar you are using isn't a truly new creation, but a reimplementation of an existing calendar. If it seems very far back, it might be an Julian Date, which has day 0 equivalent to BCE 4713 January 01 12:00:00.0 UT Monday. Julian Dates and Modified Julian dates are often used in astronomy calculations.
The next major goal is to find Jan 1, 1970 00:00:00. If you can find the number that represents that date, then you simply subtract it from this foreign calendar system and convert the remainder from the discovered units to milliseconds. That will give you UNIX time which you can then use with the standard UNIX utilities to convert to a time in any time zone you like.
In the end, you might not be able to be 100% certain that your conversion is exactly the same as the hand implemented system, but if you can test your assumptions about the calendar by plugging in numbers and seeing if they display as you predicted. Use this technique to create a battery of tests which will help you determine how this system handles leap years, etc. Remember, it might not handle them at all!
What time is: 71,867,806 miliseconds from midnight?
There are:
- 86,400,000 ms/day
- 3,600,000 ms/hour
- 60,000 ms/minute
- 1,000 ms/second
Remove and tally these units until you have the time, as follows:
How many days? None because 71,867,806 is less than 86,400,000
How many hours? Maximum times 3,600,000 can be removed is 19 times
71,867,806 - (3,600,000 * 19) = 3,467,806 ms left.
How many minutes? Maximum times 60,000 can be removed is 57 times.
3,467,806 - (60,000 * 57) = 47,806 ms left
How many seconds? Maximum times 1,000 can be removed is 47 times.
47,806 - (1,000 * 47) = 806
So the time is: 19:57:47.806
It is indeed a fairly long time ago if the smallest number is in days. However, assuming you're sure about it I could suggest the following shell command which would be obviously not valid for dates before 1st Jan. 1970:
date -d "#$(echo '(71867806-71853086)*3600*24'|bc)" +%D
or without bc:
date -d "#$(((71867806 - 71853086) * 3600 * 24))" +%D
Sorry again for the messy question, i got the solution now. In js it looks like that:
var dayZero = new Date(new Date().getTime() - 71867806 * 1000);