I'm encountering some weird behavior while using Moment.js. I have some helper classes attached to the Date prototype, which are apparently are causing each date to display behind by a day.
Date.prototype.format = function(){
return moment(this).format('MM/DD/YYYY')
}
var date = new Date('2008-05-13T00:00:00')
date.format() // => 05/12/2008, but should be 05/13/2008
A couple of other weird things I've noticed:
date.getDate() // => yields 12, but should be 13
But, if I instantiated the Moment object directly with the UTC string, then it works:
moment('2008-05-13T00:00:00').format('MM/DD/YY') // => 05/13/08
But I'm dealing with plain date objects, and modifying every date to a Moment object isn't my favorite idea. I have already tried modifying the format function to extract the UTC string from the date and see if it displays correctly then, but to no avail.
date.toUTCString() // => Correctly yields "Tue, 13 May 2008 00:00:00 GMT"
moment(date.toUTCString()).format('MM/DD/YY') // => still 05/12/08
Any ideas what's happening here? Is there a problem with the date constructor?
EDIT: Outputting the time as well:
moment(date).format('MM/DD/YY hh:mm:ss') // => "05/12/08 08:00:00"
You have to tell moment.js that you to display the date in UTC:
moment(this).utc().format('MM/DD/YYYY')
More in the documentation: http://momentjs.com/docs/#/parsing/utc/
But, if I instantiated the Moment object directly with the UTC string, then it works:
moment('2008-05-13T00:00:00').format('MM/DD/YY') // => 05/13/08`
Moment.js interprets the argument as local time:
By default, moment parses and displays in local time.
Whereas new Date() (and Date.parse) interpret the value as UTC time:
The parse function [...] interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time.
I have already tried modifying the format function to extract the UTC string from the date and see if it displays correctly then, but to no avail.
date.toUTCString() // => Correctly yields "Tue, 13 May 2008 00:00:00 GMT"
moment(date.toUTCString()).format('MM/DD/YY') // => still 05/12/08`
The format that date.toUTCString() yields is not in any of the formats that moment.js supports, so it falls back to using new Date() (which interprets the string as UTC time, not local time).
Related
I am trying to convert string to a date object in javascript, however what i day that is minus 1 from day in string. I don't know what is wrong. Here is the method
function formatDate(date_str)
{
console.log(date_str); //input : 2020-03-11
let new_date = new Date(date_str);
console.log(new_date); //output : Tue Mar 10 2020 20:00:00 GMT-0400 (Eastern Daylight Time)
return new_date;
}
The most likely explanation is that parsing the input string "2020-03-11" with no other information equates it to a date of March 11, 2020 at midnight UTC. When you are in a different time zone, then it calculates your time zone offset and gives you a time four hours earlier which would be the day before in local time.
Why such behavior:
The date string(2020-03-11) did not specify any time zone, when you attempt to create a Date object with this string, JavaScript would assume the time zone to be UTC so the date is internally dealt with like as: 2020-03-11T00:00:00Z.
console.log(new_date) would internally call .toString() method on the new_date object and doing that would trigger a date conversion to your local time zone. From the question I believe you(the time on your machine actually) are in GMT-4, this is why 4 hrs is being subtracted from the output of the logs. More details about the date conversion due to time zone here
Possible Fix:
Firstly, we should understand that this is not a bug or an error, it is just how the JavaScript Date object works.
For the scenario described in your question, I'm guessing what you want is to avoid this time zone conversion on the date string. What you can do is add timezone information to the date string before using it to instantiate a date object, with this, javascript wouldn't assume that the date string you are passing into the Date() constructor is in UTC, and when you call Date.toString() or any other similar methods, there won't be any surprises. An implementation for this can be something like this:
// Sorry for the super long function name :)
function add_local_time_zone_to_date_string (date_string) {
// Getting your local time zone
let local_time_zone = (new Date().getTimezoneOffset() * -1) / 60;
// local_time_zone is a number, convert it to a string
local_time_zone = (local_time_zone.toString())
// Padding with 0s if needed to ensure it is of length 2
local_time_zone = local_time_zone.padStart(2, '0');
return `${date_string}T00:00:00+${local_time_zone}`
}
function formatDate(date_str) {
console.log(date_str); //input : 2020-03-11
const date_with_time_zone = add_local_time_zone_to_date_string(date_str);
let new_date = new Date(date_with_time_zone);
console.log(new_date); //output : There should be no surprises here
return new_date;
}
I got timestamp utc of new york from weather api, want to display current time in New York but it gives output something like this 'UTC Sun Dec 01 2019 05:00:00 GMT+0530 (India Standard Time)'.
See the code for reference
// Code 1
//I get timestamp_utc when console.log(data)
//timestamp_utc: "2019-12-01T05:00:00"
const utc = new Date(data.timestamp_utc)
console.log('UTC', utc)
// UTC Sun Dec 01 2019 05:00:00 GMT+0530 (India Standard Time)
// Code 2
// Another code for getting current time but, failed
var usaTime = new Date().toLocaleString("en-US", {timeZone: timezone}); // Here timezone is from props
console.log('USA time: '+usaTime) // USA time: 12/1/2019, 4:59:58 AM
I also have timezone data getting from weather API. My aim is to get current time based on timezone or utc timestamp. As you can see both my trials are unsuccessful. Expected output is 6:39 PM which is now current time in New York. Is there any good solution?
Let me start with your 'code 2'. This is the same as what you wrote but with the timezone filled in...
const timezone = "America/New_York";
const usaTime = new Date().toLocaleString( "en-US", { timeZone: timezone});
console.log( 'usaTime =', usaTime );
For me this works. I get the current time in NY formatted correctly for USA. I'm not sure why yours did not work but I wonder what you specified for the timezone string.
I also a bit puzzled by your 'Code 1'. The 'new Date()' that you created is being converted to a string and then printed by your console.log statement, but this should result in a ISO 8601 string and you seem to be getting a locale string (the date format).
Though the example string you gave is in ISO 8601 format, it is not explicitly UTC because it does not end with a Z, nor does it end with a time zone offset such as +00:00. Thus when you parse it with the Date constructor, it is interpreted as local time. You can fix this by adding the Z yourself (assuming the timestamp_utc field is consistently a string in that format):
// timestamp_utc: "2019-12-01T05:00:00"
const utc = new Date(data.timestamp_utc + 'Z'); // adding the Z forces parsing as UTC
Now you have a Date object. However, if you just pass it to console.log, the output you see is implementation dependent. You will either see the local time in the same format you'd get by calling toString, or you will see the UTC time in the same format you'd get by calling toISOString.
To get the time in a different time zone, now you can call toLocaleString and pass the timeZone option. This assumes that the time zone is a valid IANA time zone identifier, and that the environment where the code is running fully supports the time zone features of the ECMAScript Internationalization Specification (ECMA-402). This is indeed the case with most modern browsers, but you will not get correct output in older browsers such as Internet Explorer.
const usEasternTime = utc.toLocaleString("en-US", {timeZone: 'America/New_York'});
Lastly from your variable name usaTime, I think perhaps you might be under the assumption that the US has a single time zone, but it does not. You will need to pass the correct time zone identifier. See the list on Wikipedia.
Define the time zones of origin ($ sourceDate) and destination (to convert).
$sourceTimeZone = 'utc';
$targetTimeZone = 'America/Bogota';
Separate the components of the date of origin that is in the format ‘m / d / y h: m: s’.
list($month, $day, $year, $hours, $minutes, $seconds) = sscanf($sourceDate, "%d/%d/%d %d:%d:%f");
Build the DateTime object indicating the date and time zone in which it is located.
$datetime = new DateTime("{$year}-{$month}-{$day} {$hours}:{$minutes}:{$seconds}",
new DateTimeZone($sourceTimeZone));
Modify the time zone of the DateTime to the destination time zone.
$datetime -> setTimezone(new DateTimeZone($targetTimeZone));
Get the components of the new date with the modified time zone.
list($month2, $day2, $year2, $hours2, $minutes2, $seconds2) = sscanf($datetime -> format(‘m/d/Y H:i:s’), “%d/%d/%d %d:%d:%f”);
Show the dates.
echo "En {$sourceTimeZone}: {$day}/{$month}/{$year} {$hours}:{$minutes}:{$seconds}<br/>";
echo "En {$targetTimeZone}: {$day2}/{$month2}/{$year2} {$hours2}:{$minutes2}:{$seconds2}<br/>";
PD: For JavaScript this can help you Convert time to different timezone with jQuery
I was trying to post some data to my REST api which has date.
Now while I debug, my date parameter is a JS Date object with correct date in my timezone: Tue Apr 04 2017 00:00:00 GMT+0530
after it leaves my code, and I see the same in network tab, it is converted to UTC date: "2017-04-03T18:30:00.000Z"
I searched for the solution according to which I need to include locale file of angular in my index.html which I did:
<script type="text/javascript" src="resources/js/angular/angular-locale_en-in.js"></script>
but it doesn't help.
I've seen solutions like adding date format to filter or something, but I want a global solution.
Any help?
Thanks :)
Handling date, time, and timezone have confused me too. May be this answer gives you some insight on how you can handle them.
Try the following code in Chrome's developer console and see how same date is presented in different formats:
var date = new Date();
date.toISOString(); // "2017-04-29T09:54:28.714Z"
date.toGMTString(); //"Sat, 29 Apr 2017 09:54:28 GMT"
date.toLocalString(); //"4/29/2017, 3:24:28 PM"
Any date that you create on client always records the date at zero timezone offset i.e. UTC+/-00:00 Z. For simplicity you may think UTC and GMT as same. When it comes to display purpose the same date is presented as per the browser's timezone. If you do console.log (date) it'll output Sat Apr 29 2017 15:24:28 GMT+0530 (IST) but that doesn't mean that the internal recording of the date is as per browser's timezone. It's just presented on screen/console as per browser's timezone.
Look at date representations not as being converted from one timezone to another but look at them as different representation of the same date. In your browser it is represented as GMT+0530 offset and when it is sent to server it is the same date at zero timezone offset.
As per your comment, if you choose 4th Apr at 00:00 AM in GMT+0530 timezone, internally it'll be 3rd Apr at 18:30 PM in at GMT+0 i.e. zero timezone offset. Let it go to server as it is. When you need to use this date, it comes back from server as 3rd Apr and it'll be displayed in browser as per the browser's timezone offset. There is no conversion involved, it is one date with different representation.
I once asked a related question, may be this adds more clarification.
And overall, this answer is still same as #geminiousgoel and #charlietfl answers.
Scenario :
Send date from UI into API call as an epoch time (UNIX Time) instead of date string. You can use getTime() method to convert the date into epoch time.
var dateStr = "Tue Apr 04 2017 00:00:00 GMT+0530";
var dateEpoch = new Date(dateStr).getTime();
console.log(dateEpoch); // 1491244200000 (Local Time)
At receiver end, they have to convert this epoch time (UNIX time) into Date again.It will give the same local date\time that pass from the UI.
Sample screenshot
Like charlietfl suggested, probably the global hack would be to override Date.prototype.toJSON() method, but that's not a good practice.
Where are you using your $http.post call? The best place to submit an $http request would be in a service. If you use a service, then I suggest you to enwrap your public service API, so that you could have "public" and "private" methods: these could be utilities to perform common operations, such as data transformations, validations..
angular.service('bookStoreService', ['$http'], function($http) {
var normalizeBooks = function(booksArray){
booksArray.forEach(function(book){
// do something on the book
});
};
var updateBooks = function(books){
normalizeBooks(books);
$http.post('myurl', books);
};
return {
updateBooks : updateBooks
};
});
Passing UTC date to server is desired behavior. The client APIs are supposed to handle UTC time instead of assuming the dates are all local dates.
But anyways, you can convert the date to string based on local time zone, and pass the string to server.
i think you just can pass it as string (if the api you use accept strings) with the format you need, let say "Tue Apr 04 2017 00:00:00 GMT+0530" and save it in back-end as string and then when you retrieve it, it will be string and so it will not be changed in any way.
Jindal saab, It will work like this. When we select any date with date picker or just pass any value it takes the original local date but when we pass that value further it converts it into UTC, thereafter it needs to convert to local zone again at receiving end. Database saves date-time in UTC format.
Did you added the angular-locale_en-in.js library to your app? Something like this....
angular.module('myAngularApp', [
'ngLocale'])
Otherwise, the js library won't have any effect in your angular application.
Append UTC at the end so that Browser converts it into UTC date
var dateToServer =new Date(dateFromUser+" UTC");
now the dateToServer will be UTC DateTime format.
Json serializer parse date from string. On a client the date properties are stored as local date in browser time zone. When you are posting your object to server all date properties converts to utc string. In most cases it is a properly behavor. But sometimes you need set and send date in a server time zone. Often it is need when you should set only date whitout time. In that case you should define string propertie and set it manualy. I usaly apply this trick.
class Obj{
d: Date
}
class ObjDto{
constructor(obj: Obj){
this.d= dateTimeToIsoLocalDateString(obj.d)
}
d: string
}
...
export function DateTimeToDate(date) {
return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
}
export function dateTimeToIsoLocalDateString(dateTime: Date): string {
if (dateTime === null) {
return null;
}
let date = DateTimeToDate(dateTime);
let res = date.toISOString().replace("Z", "");
return res;
}
For more understanding this theme you may learn this topic
//in res data of rest service in x the value is date in y value of y-axis
for (const i in res) {
console.log(i);
const a = {x: new Date(this.mimikatzlog[i].x), y: this.mimikatzlog[i].y};
this.policies.push(a);
I have these 2 console logs, but they return different times (-2 hours off).
console.log(new Date()) // Date 2015-04-20T15:37:23.000Z
console.log(Date()) // "Mon Apr 20 2015 17:37:23 GMT+0200 (CEST)"
I know using Data() is the same as using the constructor and calling .toString().
However, i do need the Date() time and not the new Date() time. So why is it returning the wrong time and how can i reset it to output the correct one?
thx,
So why is it returning the wrong time and how can i reset it to output the correct one?
Your first statement is calling console.log with a Date object. It appears that whatever browser/console plugin you're using chooses to display that Date object by using an ISO-8601 string in UTC. E.g., the format is chosen by the console implementation.
Your second statement is calling console.log with a string, so the format is chosen by the Date implementation. The specification makes no requirement on what that string format must be from JavaScript engine to JavaScript engine (yes, really*) other than that it must be in the local timezone.
Apparently, on your browser, the console implementation and the Date#toString implementation don't match up.
However, i do need the Date() time and not the new Date() time.
Those strings define the same moment in time (plus or minus a couple of microseconds); it's just that the strings have been prepared with different timezone settings.
If you need to log a string to the console in local time, use
console.log(String(new Date()));
...to reliably get the string from the Date object, not something generated by the console.
* Yup, the format you get from Date#toString is undefined and entirely up to the JavaScript implementation; the only requirement is that Date() and Date.parse() can both parse the string toString outputs and get back to the original date. (JavaScript didn't even have a standard date/time format until ES5, and it only applies to the toISOString method, not toString. And ES5 got it slightly wrong and it had to be amended in ES6, leading to the unfortunate situation at the moment where Chrome does one thing and Firefox does another when parsing strings in the new date/time format with no timezone on them.)
Those are the same time. The string generated by Date() just uses a different timezone, as can be seen from the GMT+0200 (CEST) suffix.
So if you need your time string in your local timezone, just use .toString() instead of .toUTCString().
I'm located in PST timezone and I want to be able to take the string "2014-01-01" and convert it into Unix time without "2014-01-01" getting converted to PST.
Here's what I'm doing:
Date.parse(new Date("2014-01-01"))
I'm getting the value 1388534400000 which is equivalent to Tue Dec 31 2013 16:00:00 GMT-0800 (Pacific Standard Time)
I want to take the date as "2014-01-01" and not convert it into PST before converting it into Unix time.
A few things:
The Date constructor returns a Date object, not a string. You shouldn't wrap it in a call to Date.parse.
If you want a unix timestamp, just call getTime().
var ts = new Date("2014-01-01").getTime();
Alternatively, you can parse the date string without creating a Date object at all.
var ts = Date.parse("2014-01-01");
The behavior of date parsing in JavaScript is implementation dependent. Most browsers will already interpret a yyyy-mm-dd string to be in UTC, due to the dashes (-). If you replace with with slashes (/), you'll see the string get interpreted as local time instead.
I think you're confused about the output. You said the timestamp was equivalent to PST, but that's just one representation. It's also equivalent to the UTC value you passed in. It's not getting converted in the input, it's being converted when you are converting the timestamp back to local time.
You can use a library like moment.js, which gives you full control of the input and output. This is usually the best option, but has the overhead of including a library in your application.
Another way to convert the specified date string to Unix time is as follows:
var str = "2014-01-01";
var parts = str.split('-');
parts[1] -= 1; // js numeric mos are 0-11
var ms = Date.UTC( parts[0], parts[1], parts[2] ); // parts: YYYY, MM, DD
var unix_time = ms/1000; // Unix time uses seconds
console.log("Unix time: " + unix_time);
Date.UTC() returns the number of milliseconds occurring since January 1, 1970 midnight up to the instant of the specified date, irrespective of any timezone. The script transforms the result into Unix time, i.e. seconds, by dividing the number of milliseconds by 1000.
After splitting the string into an array, the code adjusts the element containing the month, lest JavaScript mistake its value for March; JavaScript comprehends numeric months as ranging from 0-11, not 1-12. Next, the script passes the elements sequentially in accordance with the year, month, day parameters that Date.UTC requires. Although UTC() expects numbers for parameters, it accepts the numerical strings.
Note: if you first create a new date object and expect to use a UTC method -- that results in an error because it is a static method of JavaScript's Date Object.
You may check the validity of the UTC() return value, using the aforementioned variables ms and str, as follows:
console.log( new Date( str ).toUTCString( ms ));
The output: Wed, 01 Jan 2014 00:00:00 GMT
See live demo here)
Passing a date string to the Date constructor instead of the numerical parameters it expects affords an unexpected benefit; the date string is treated as if it's timezone is UTC, i.e. zero by the local date object. Once created, the local date object executes its toUTCString() method to attain the above-indicated result. The toString() method would also yield the same output, but it appends local timezone information.