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.
Related
I need to send my current date on UI as http request header to Java based webservice but facing issue as the javascript new Date method hides the millisecond data from date and forwards it to web service.
console.log(new Date())
LOGS - Thu Sep 07 2017 14:47:37 GMT+0530 (India Standard Time)
The millisecond information is not present. I however need that in a date type that Java webservice also considers as Date and not string. I read about momentjs format approach but that basically returns a string and not date.
What I need is like: Thu Sep 07 2017 15:10:46:955GMT+0530 (India Standard Time).
ECMAScript Dates are based on a time value that is milliseconds since 1970-01-01T00:00:00Z, so they are inherently UTC. Therefore the value returned by:
new Date().getTime();
// or more concisely
Date.now();
does not need a timezone and includes millisecond precision. You can also use toISOString which returns an ISO 8601 extended date with milliseconds, again using UTC, e.g. 2017-09-07T22:51:51.287Z.
The ISO format is very widely accepted, is conveniently human readable and is unambiguous.
However, if it's important to also convey the timezone of the source, you can use the timezone offset (which is returned in minutes to add to local time to get UTC) and format it to something more standard.
function getISOOffset(date) {
date = date || new Date();
function z(n){return ('0'+n).slice(-2)}
var offset = date.getTimezoneOffset();
// ECMScript offset sign is the reverse of ISO 8601
var sign = offset < 0? '+' : '-';
offset = Math.abs(offset);
return sign + z(offset/60 | 0) + ':' + z(offset % 60);
}
console.log('The host offset is UTC' + getISOOffset())
If you are ok with purely milliseconds you can use something like this:
Date.now(); // 1504785573971
This works on almost all modern browsers. It doesn't tell you the timezone of the user, but does give you a consistent number against which to compare (milliseconds since Midnight of January 1, 1970, GMT).
For the very specific timestamp you seek, you might need a library like moment.js - it's a pretty heavy solution, but gives you excellent control over formatting.
Moment.js Formatting Options
This will be a string as there is not truly agreed-upon formation for passing dates in JSON. It will require parsing logic in the Java. I don't have much experience on the Java side, but I believe the popular libraries like Jackson and GSON support this conversion.
If you are not using JSON to submit information to the server, normal form submissions are passed as a string and have to be parsed out on the server, anyway.
The server uses +03:00 timezone. It offers me a date in this format: "2017-04-12T00:00:00+03:00"
I then create a new Date from this string:
options.startDate = new Date("2017-04-12T00:00:00+03:00")
But because on the client there is a different timezone, the result is actually:
Tue Apr 11 2017 23:00:00 GMT+0200 (Central Europe Daylight Time)
This brings me back one day and it's a big deal for me. Is there an elegant way to avoid this and create the same Date and Time in javascript, ignoring the timezone offset?
The date you have in options.startDate is the correct one. What you want is to display it as if you were from the same timezone as the server.
If you now server's timezone in the client script then I would considere using a library like moment.js. It would allow you to format date in the timezone you want (GMT for instance, or the one of the server).
Using both moment.js and its plugin timezone code could be :
moment("2017-04-12T00:00:00+03:00").tz("America/Los_Angeles").format();
You should never use the Date constructor or Date.parse to parse strings due to browsers differences. Even if you remove the timezone from the string and parse the remainder, e.g.
console.log( new Date('2017-04-12T00:00:00+03:00'.substr(0,19)).toString() );
you'll get different results in different browsers (e.g. Firefox and Safari).
If you don't want to use a library, use a simple function (see below). However, if you remove the timezone, the string will represent a different moment in time in each timezone with a different offset.
function parseISOIgnoreTimezone(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
}
console.log(parseISOIgnoreTimezone('2017-04-12T00:00:00+03:00').toString());
I really recommend #VictorDrouin his answer.
But if for some reason you don't want moment.js or fiddle around with it you can use this 'hack'
new Date("2017-04-12T00:00:00+03:00".match(/\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}/).pop());
What it does it matches the date against given regex date format, and then supplies it to the date parser which makes it a date.
Be careful when supplying it back to the database that you supply it back without timezone offset.
var stringdate = "2017-04-12T00:00:00+03:00";
function getDate(str_date) {
var matched = str_date.match(/\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}/).pop();
return new Date(matched);
}
console.log(getDate(stringdate));
I have dates stored in my database in UTC format and calling
element.createdDate = new Date(element.createdDate.toString());
results in displaying the wrong date.
calling
element.createdDate = new Date(element.createdDate.toUTCString());
returns nothing. How do I go about displaying the correct time from UTC?
It appears that your json response contains a string valued which are in ISO8601 format in UTC, and then you are creating Date objects from them.
This part of your code is fine:
if (element.createdDate) element.createdDate = new Date(element.createdDate.toString());
You parse the string, and the resulting Date object is correct.
However, you don't need to use .toString() here, as the value is already a string. That is redundant.
This part of your code is the problem:
console.log("javascript date: " + new Date(element.depositDate.getUTCDate().toString()));
The getUTCDate function returns just the date of the month. Don't use that.
No matter what you do to create the Date object, ultimately you create a Date object and you're relying upon an implicit string conversion to output it. This will have different behavior in different browsers.
Consider console.log(new Date()):
In Chrome, this logs something like Fri Mar 17 2017 12:14:29 GMT-0700 (Pacific Daylight Time) on my computer. This is as if I called console.log(new Date().toString()); It is in an RFC 2822 like format (but not quite), and is represented in local time.
In Firefox, this logs something like 2017-03-17T19:14:46.535Z. This is as if I called console.log(new Date().toISOString()); It is in ISO8601 format, and is represented in UTC.
The point is, don't rely on implicit undefined behavior. If you must work with Date objects, then you should use console.log(element.createdDate.toISOString()) to see the ISO8601 representation of the UTC time.
If you're going to be doing a lot of things with dates and times, you may prefer to use a library, such as Moment.js, which can make tasks such as this more clear.
I have dates stored in my database in UTC format and calling
element.createdDate = new Date(element.createdDate.toString());
results in displaying the wrong date.
2016-10-11T00:00:00Z and Mon Oct 10 2016 20:00:00 GMT-04:00 (EDT) are exactly the same moment in time. The only difference is that one is displayed in ISO 8601 extended format with timezone offset 00:00 and the other is displayed in an RFC 2822 (like) format with timezone offset -04:00 (and assumes a locality in the EDT region).
calling
element.createdDate = new Date(element.createdDate.toUTCString());
returns nothing.
That is unusual. Typically it would return either a string or an error, but without a working example or any code to provide context it's impossible to say why.
How do I go about displaying the correct time from UTC?
You haven't specified what "correct" is. You are displaying a date and time for the same moment in time, just in a different format and time zone.
I'm trying to convert a GMT time to the user's Local time.
the format of the time i'm getting from the server is : 2015-05-20 18:00:00 GMT
I just want to show hours and minutes like that : 20:00
I wanted to use this solution which seems pretty easy, but I don't know how to make my format same as this
var date = new Date('5/21/2015 18:52:48');
date.toString();
the format of the time i'm getting from the server is : 2015-05-20 18:00:00 GMT
If so, you can easily massage that into a format that ES5 and higher browsers are supposed to support, which would be 2015-05-20T18:00:00Z for your example:
var yourString = "2015-05-20 18:00:00";
var dt = new Date(yourString.replace(' ', 'T') + "Z");
var hours = dt.getHours(); // Will be local time
var minutes = dt.getMinutes(); // Will be local time
Then just format the hours and minutes values you get into your desired hh:mm string.
Note: The Z at the end of the string is important. Unfortunately, the ES5 specification has a significant error in it (they're fixing it in ES6) around what the engine should do if there is no timezone on the string being parsed. Some engines do what the spec says, others do what the spec should have said (and the ES6 spec will say), which unfortunately means that right now, you can't trust what browsers will do if there's no timezone on the string.
I just had to add " UTC "
var date = new Date('2015-05-20 15:00:00 UTC');
alert(date.getHours());
alert(date.getMinutes());
new Date() in browser returns date object in user's timezone(machine timezone).
Just you need to pass GMT date to Date function in ISO format. So it will treat it as gmt time.
var date = new Date('2015-05-21T18:52:48Z');
date.toString();//You will get here date string in local format
You can also use UTC as UTC and GMT are same.
Here is ex.
var date = new Date('2015-05-21 18:52:48UTC'); //You can use GMT instead UTC
date.toString();//You will get here date string in local format
First method is preferable as second method doesn't work on Internet Explorer
I've read this question:
How do you convert a JavaScript date to UTC?
and based on this I implemented this conversion in a dateTools module as follows:
[Update]
var dt, utcTime;
dt = new Date();
utcTime = new Date(Date.UTC(dt.getFullYear(),
dt.getMonth(),
dt.getDate(),
dt.getHours(),
dt.getMinutes(),
dt.getSeconds(),
dt.getMilliseconds()));
Now I'd like to write unit tests. My idea was to check whether the result is actually in UTC, but I don't know how.
All the toString, toUTCString and similar methods seem to be identical for the input (non UTC) and output (UTC) date.
Only the result of the getTime method differs.
Is there a way to check wheter a date is UTC in javascript? If not, is there a better idea to unit test this?
To give more context:
Only converting the it to a UTC string is not that helpful, because in the next step the date is sent to an Asp.net service and therefore converted to a string like:
'/Date([time])/'
with this code
var aspDate = '/Date(' + date.getTime() + ')/';
var aspDate = '/Date(' + date.getTime() + ')/';
This outputs the internal UNIX epoch value (UTC), which represents a timestamp. You can use the various toString methods to get a more verbose string representation of that timestamp:
.toString() uses the users timezone, result is something like "Fri Jan 25 2013 15:20:14 GMT+0100" (for me, at least, you might live in a different timezone)
.toUTCString() uses UTC, and the result will look like "Fri, 25 Jan 2013 14:20:15 GMT"
.toISOString() uses UTC, and formats the datestring according to ISO: "2013-01-25T14:20:20.061Z"
So how do we construct the time value that we want?
new Date() or Date.now() result in the current datetime. No matter what the user's timezone is, the timestamp is just the current moment.
new Date(year, month, …) uses the users timezone for constructing a timestamp from the single values. If you expect this to be the same across your user community, you are screwed. Even when not using time values but only dates it can lead to odd off-by-one errors.
You can use the setYear, setMonth, … and getYear, getMonth … methods to set/get single values on existing dates according to the users timezone. This is appropriate for input from/output to the user.
getTimezoneOffset() allows you to query the timezone that will be used for all these
new Date(timestring) and Date.parse cannot be trusted. If you feed them a string without explicit timezone denotation, the UA can act random. And if you want to feed a string with a proper format, you will be able to find a browser that does not accept it (old IEs, especially).
Date.UTC(year, month, …) allows you to construct a timestamp from values in the UTC timezone. This comes in handy for input/output of UTC strings.
Every get/set method has a UTC equivalent which you can also use for these things.
You can see now that your approach to get the user-timezone values and use them as if they were in UTC must be flawed. It means either dt or utcTime has the wrong value, although using the wrong output method may let it appear correct.
getTimezoneOffset
Syntax: object.getTimezoneOffset( ) This method
returns the difference in minutes between local time and Greenwich
Mean Time. This value is not a constant, as you might think, because
of the practice of using Daylight Saving Time.
i.e.
var myDate = new Date;
var myUTCDate = new Date(myDate - myDate.getTimezoneOffset() * 60000);
alert(myUTCDate);
note: 60000 is the number of milliseconds in a minute;