I understand that dealing with dates, in any environment, could be quite confusing, but I'm in a nightmare with a function that should be a trivial job.
I want to manipulate in different ways some dates, but I get errors or wrong results.
I report hereafter a very simple example made to test the execution; the goal here is to get the current month beginning date, just to show what happens:
function DateAdjust() {
var newdate = new Date(); //1: 2018-12-12T21:00:20.099Z
newdate = newdate.setDate(1); //2: 1543698020099
newdate=Date(newdate); //3: Wed Dec 12 2018 21:01:43 GMT+0000 (Ora standard dell’Europa occidentale)
var d = newdate.getDate(); //4: newdate.getDate is not a function
}
4 lines, 3 unexpected results (as shown by Firefox's debugger):
1. the starting date has no day-of-week and no timezone
2. setting the day, result is transformed in milliseconds (why?); I do not know if it is correct.
3. reconverting in string gives the original date, unmodified (why?) but with week day and timezone
4. trying to get the day value an error is thrown (why?)
My environment:
Win 7 32bits SP1
Firefox 63.0.3 (32 bit)
jquery-2.2.4.min.js
I know these questions are boring, but hope someone will find few minutes to clear my mind.
Regarding line 1, the Z at the end is the timezone designation for UTC in ISO 8601 (see Wikipedia).
If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset. "09:30 UTC" is therefore represented as "09:30Z" or "0930Z". "14:45:15 UTC" would be "14:45:15Z" or "144515Z".
Regarding line 2 see the MDN article on setDate (emphasis mine):
The number of milliseconds between 1 January 1970 00:00:00 UTC and the given date (the Date object is also changed in place).
So you can see the 'correct' behavior you probably expect simply by ignoring the return value:
var newdate = new Date(); //1: 2018-12-12T21:00:20.099Z
newdate.setDate(1); //2: 1543698020099
console.log(newdate); //3: 2018-12-01T21:00:20.099Z
Regarding line 3, see MDN article on Date (emphasis mine):
Note: JavaScript Date objects can only be instantiated by calling
JavaScript Date as a constructor: calling it as a regular function
(i.e. without the new operator) will return a string rather than a
Date object; unlike other JavaScript object types, JavaScript Date
objects have no literal syntax.
Regarding line 4, the above also explains this error, since newdate is now a string rather than a Date object.
For what it's worth, I agree with the other commenters. JavaScript's date functions are pretty messy compared to many other modern languages. I strongly recommend using a library like moment, luxon, or date-fns. It'll make your life much easier.
I do recommend using moment.js
But there are 2 problems with your code:
1-
newdate = newdate.setDate(1);
setDate mutates newDate in place, and return it in miliseconds, not a new Date object. If you just want to set the date, do this instead:
newdate.setDate(1);
2-
newdate=Date(newdate);
Not realy sure why you are trying to get a new Date object, but you need the new, otherwise it will just be a string
newdate= new Date(newdate);
Fixing problem 1 should eliminate the need for the code of problem 2
var newdate = new Date(); // 1
console.log(typeof newdate, newdate); // object Wed Dec 12 2018 23:00:44 GMT+0200 (Eastern European Standard Time)
newdate = newdate.setDate(1); // 2
console.log(typeof newdate, newdate); //number 1543698085383
newdate=Date(newdate); //3
console.log(typeof newdate, newdate); //string Wed Dec 12 2018 23:04:44 GMT+0200 (Eastern European Standard Time)
var d = newdate.getDate(); // 4
console.log(typeof d, d); //
Date type is assigned to the object.
number is assigned to newdate. which is ticks
returns string
string.getDate() is not defined, so undefined.
hope it helps.
Related
When I try to parse a string date from March, new Date() works incorrectly. But when my string date is from April, everything is fine. I don't understand this. Why does it work like that?
var a = '2018-03-07T00:00+03:00';
console.log(a);
console.log(new Date(a).toString());
var b = '2018-04-07T00:00+03:00';
console.log(b);
console.log(new Date(b).toString());
Here's a screenshot from Google Chrome browser:
As others pointed out, it's due to the daylight saving time in your time-zone. Notice the times in your screenshot: the time for a is 23 and for b is midnight 00, which clearly tells you what happened.
If you want to parse the values without the daylight saving time, you can use the GMT+0 time-zone by replacing your time-zone +3:00 with z. However, then you need to correct time manually by adding/subtracting the hours of your time-zone (-3 in your case). Here is an example:
var a = '2018-03-07T00:00+03:00';
a.replace('+03:00', 'z');
a = new Date(a);
a.setHours(a.getHours() - 3); //3 is your time-zone
console.log(a.toUTCString());
var b = '2018-04-07T00:00+03:00';
b.replace('+03:00', 'z');
b = new Date(b);
b.setHours(b.getHours() - 3); //3 is your time-zone
console.log(b.toUTCString());
Obviously, this code will only work for one known time-zone. If your values can be in different time-zone, then instead of replacing, you need to extract the time-zone from the string (the last 6 characters in this format, except for GMT-0 which is z), and then use it to correct the time on the setHours() line.
Because of summer daylight saving time. According to Date documentation, the date is specific moment in time relative to Jan 1st 1970. That moment in time in March belonged to the part of year with daylight saving offset in your specific locale
Your first date is Standard Time... and the second one is Daylight Time.
var x = new Date('2018-03-07T00:00+03:00');
console.log(x);
var y = new Date('2018-04-07T00:00+03:00');
console.log(y);
In your scenario... EET – Eastern European Time versus EEST – Eastern European Summer Time like shown on console.
In a more general sense, I'm wondering if a value in Javascript can behave as if no variable were input, so that new Date(whatever) functions exactly like new Date().
null doesn't do this, instead creating a Date of (I think) -1 UNIX seconds (the very end of 1969). Is there a string that would work, e.g "now"?
You can use
new Date(Date.now());
to get the current date. Typing that into the console would return (for today's date)
Wed Jul 12 2017 14:03:16 GMT-0400 (Eastern Daylight Time)
To clarify, Date.now() returns the number of milliseconds since January 1, 1970 at 0:00 UTC.
You can read more about Date here : MDN: Date - JavaScript
No, there is no single value that would instruct new Date(…) with one argument to use the current time. However, you can call Date.now() or new Date() to get the current time, and then pass that to the constructor, which will return a new Date instance with that time.
I am based in Australia and while new Date() give me the current date and time in Australia, for instance
Fri Aug 26 2016 09:16:16 GMT+1000 (AUS Eastern Standard Time)
, if I write new Date().toJSON()
I get 2016-08-25T23:20:08.242Z,
how can I get the same format as in yyyy-mm-ddThh:mn:ss but keeping my local day and time, ie it should be the 26 and not the 25th.
Edit: when I write programmatically new Date(2016, 11, x) with var x = 31, using toJSON() I have no guarantee to see displayed 2016-12-31 because of timezones, so was wondering is there is a different javascript function that would give me the intended result.
I would use moment.js for that.
var date = moment("Fri Aug 26 2016 09:16:16 GMT+1000");
console.log(moment(date).format('YYYY-MM-DD T hh:mm:ss'));
https://jsfiddle.net/Refatrafi/ys4nu8o9/
toJSON() returns timestamps in ISO 8601 format. Z at the end of string means that used UTC. Date objects in ECMAScript are internally UTC. The specification for Date.prototype.toJSON says that it uses Date.prototype.toISOString, which states that "the timezone is always UTC".
The date isn't wrong, it's in UTC. Without timezone information, yyyy-mm-ddThh:mn:ss is meaningless unless you explicitly want to assume that it's in the AEST timezone.
If you're transmitting the date as a string to be parsed back into some sort of Date-like object later on (by your webserver, for example), there's nothing you need to do. 2016-08-25T23:20:08.242Z unambiguously refers to the same point in time no matter what you use to parse it.
If you're trying to format the date object and display it somewhere, you can extract the different parts of the Date object and build up the representation you want:
function format_date(d) {
var pretty_date = [d.getFullYear(), d.getMonth() + 1, d.getDate()].join('-');
var pretty_time = [d.getHours(), d.getMinutes(), d.getSeconds()].join(':');
return pretty_date + 'T' + pretty_time;
}
As the other answers have pointed out, if you plan on working more with dates, consider using a library that makes it easier. JavaScript doesn't have a very rich API, so you'll have to write more code.
I'm creating dates like this:
var StartDate = new Date(data.feed.entry[i].gd$when[j].startTime);
When a date string is received specifying date and time in the form:
"2014-04-12T20:00:00.000-05:00"
Date() interprets this perfectly fine returning:
Sat Apr 12 2014 19:00:00 GMT-0500 (CDT)
However, when the date string is received with no time information in the form:
"2014-04-07"
then Date() is interpreting it as:
Sat Apr 05 2014 19:00:00 GMT-0500 (CDT)
Looks like Date() is taking the -07 as the time and I have no clue where is it getting the date as 05. Any idea what might be the problem?
Could it be, somehow, Date() is interpreting a different time zone because in the first string the time zone is determined at the very end but in the "all day" event there is no indication of the time zone.
Has anybody found this issue? If yes, how did you solve it?
UPDATE: After researching a little bit more this parsing issue I noticed something very weird:
The following statement:
new Date("2014-4-07")
would return Mon Apr 07 2014 00:00:00 GMT-0500 (CDT) which is correct, but the following one:
new Date("2014-04-07")
returns Sun Apr 06 2014 19:00:00 GMT-0500 (CDT) which is the wrong one. So, for whatever reason, seems like the padding zeros affect the way the date is parsed!
You're using the Date() function wrong.
It only accepts parameters in the following formats.
//No parameters
var today = new Date();
//Date and time, no time-zone
var birthday = new Date("December 17, 1995 03:24:00");
//Date and time, no time-zone
var birthday = new Date("1995-12-17T03:24:00");
//Only date as integer values
var birthday = new Date(1995,11,17);
//Date and time as integer values, no time-zone
var birthday = new Date(1995,11,17,3,24,0);
Source: MDN.
The Date() function does not accept timezone as a parameter. The reason why you think the time-zone parameter works is because its showing the same time-zone that you entered, but that's because you're in the same time-zone.
The reason why you get Sat Apr 05 2014 19:00:00 GMT-0500 (CDT) as your output for Date("2014-04-07" ) is simply because you used it in a different way.
new Date(parameters) will give the output according to the parameters passed in it.
Date(parameters) will give the output as the current date and time no matter what parameter you pass in it.
Prior to ES5, parsing of date strings was entirely implementation dependent. ES5 specifies a version of ISO 8601 that is supported by may browsers, but not all. The specified format only supports the Z timezone (UTC) and assumes UTC if the timezone is missing. Support where the timezone is missing is inconsistent, some implementations will treat the string as UTC and some as local.
To be certain, you should parse the string yourself, e.g.
/* Parse an ISO string with or without an offset
** e.g. '2014-04-02T20:00:00-0600'
** '2014-04-02T20:00:00Z'
**
** Allows decimal seconds if supplied
** e.g. '2014-04-02T20:00:00.123-0600'
**
** If no offset is supplied (or it's Z), treat as UTC (per ECMA-262)
**
** If date only, e.g. '2014-04-02', treat as UTC date (per ECMA-262)
*/
function parseISOString(s) {
var t = s.split(/\D+/g);
var hasOffset = /\d{2}[-+]\d{4}$/.test(s);
// Whether decimal seconds are present changes the offset field and ms value
var hasDecimalSeconds = /T\d{2}:\d{2}:\d{2}\.\d+/i.test(s);
var offset = hasDecimalSeconds? t[7] : t[6];
var ms = hasDecimalSeconds? t[6] : 0;
var offMin, offSign, min;
// If there's an offset, apply it to minutes to get a UTC time value
if (hasOffset) {
offMin = 60 * offset / 100 + offset % 100;
offSign = /-\d{4}$/.test(s)? -1 : 1;
}
min = hasOffset? +t[4] - offMin * offSign : (t[4] || 0);
// Return a date object based on UTC values
return new Date(Date.UTC(t[0], --t[1], t[2], t[3]||0, min, t[5]||0, ms));
}
An ISO 8601 date string should be treated as UTC (per ECMA-262), so if you are UTC-0500, then:
new Date('2014-04-07'); // 2014-04-06T19:00:00-0500
The behaviour described in the OP shows the host is not compliant with ECMA-262. Further encouragement to parse the string yourself. If you want the date to be treated as local, then:
// Expect string in ISO 8601 format
// Offset is ignored, Date is created as local time
function parseLocalISODate(s) {
s = s.split(/\D+/g);
return new Date(s[0], --s[1], s[2],0,0,0,0);
}
In your function you can do something like:
var ds = data.feed.entry[i].gd$when[j].startTime;
var startDate = ds.length == 10? parseLocalISODate(ds) : parseISOString(ds);
Also note that variables starting with a capital letter are, by convention, reserved for constructors, hence startDate, not StartDate.
(I would add a comment but i don't have 50 rep yet)
See what
new Date().getTimezoneOffset()
returns, I would expect a big negative value, that would be the only reasonable explanation to your problem.
I have had some trouble with date conversions in the past, in particular with daytime saving timezones, and as work around i always set the time explicitly to midday (12:00am). Since I think you were using knockout, you could just make a computed observable that appends a "T20:00:00.000-05:00" or the appropiate time zone to all "day only" dates
I was trying to convert date object into long format (may be in milliseconds format) as we do in java.
So to fulfill my need, after some trial and error, I found below way which works for me:
var date = new Date();
var longFormat = date*1; // dont know what it does internally
console.log(longFormat); // output was 1380625095292
To verify, I reverse it using new Date(longFormat); and it gave me correct output. In short I was able to fulfill my need some how, but I am still blank what multiplication does internally ? When I tried to multiply current date with digit 2, it gave me some date of year 2057 !! does anyone know, what exactly happening ?
The long format displays the number of ticks after 01.01.1970, so for now its about 43 years.
* operator forces argument to be cast to number, I suppose, Date object has such casting probably with getTime().
You double the number of milliseconds - you get 43 more years, hence the 2057 (or so) year.
What you are getting when you multiply, is ticks
Visit: How to convert JavaScript date object into ticks
Also, when you * 2 it, you get the double value of ticks, so the date is of future
var date = new Date()
var ticks = date.getTime()
ref: Javascript Date Ticks
getTime returns the number of milliseconds since January 1, 1970. So when you * 1 it, you might have got value of this milliseconds. When you * 2 it, those milliseconds are doubled, and you get date of 2057!!
Dates are internally stored as a timestamp, which is a long-object (more info on timestamps). This is why you can create Dates with new Date(long). If you try to multiply a Date with an integer, this is what happens:
var date = new Date();
var longFormat = date*1;
// date*1 => date.getTime() * 1
console.log(longFormat); // output is 1380.....
Javascript tries to find the easiest conversion from date to a format that can be multiplied with the factor 1, which is in this case the internal long format
Just use a date object methods.
Read the docs: JavaScript Date object
var miliseconds=yourDateObject.getMiliseconds();
If You want to get ticks:
var ticks = ((yourDateObject.getTime() * 10000) + 621355968000000000);
or
var ticks = someDate.getTime();
Javascript date objects are based on a UTC time value that is milliseconds since 1 January 1970. It just so happens that Java uses the same epoch but the time value is seconds.
To get the time value, the getTime method can be used, or a mathematic operation can be applied to the date object, e.g.
var d = new Date();
alert(d.getTime()); // shows time value
alert(+d); // shows time value
The Date constructor also accepts a time value as an argument to create a date object, so to copy a date object you can do:
var d2 = new Date(+d);
If you do:
var d3 = new Date(2 * d);
you are effectively creating a date that is (very roughly):
1970 + (2013 - 1970) * 2 = 2056
You could try the parsing functionality of the Date constructor, whose result you then can stringify:
>
new Date("04/06/13").toString()
"Sun Apr 06 1913 00:00:00 GMT+0200"
// or something
But the parsing is implementation-dependent, and there won't be many engines that interpret your odd DD/MM/YY format correctly. If you had used MM/DD/YYYY, it probably would be recognized everywhere.
Instead, you want to ensure how it is parsed, so have to do it yourself and feed the single parts into the constructor:
var parts = "04/06/13".split("/"),
date = new Date(+parts[2]+2000, parts[1]-1, +parts[0]);
console.log(date.toString()); // Tue Jun 04 2013 00:00:00 GMT+0200