I am using momentjs for doing my date operations and want to code a scenario where if timestamp is given, and timezone name is given, then I want to reset the time to midnight. For e.g.
let timestamp = 1493638245234;
expect(new Date(timestamp).toISOString()).toBe('2017-05-01T11:30:45.234Z'); // Time in UTC
let truncatedTimestamp = functionName(timestamp, 'America/Los_Angeles');
console.log(truncatedTimestamp);
expect(new Date(truncatedTimestamp)).toBe('2017-05-01T04:00:00.000Z');
const functionName = (timestamp, timezone) => {
return moment
.tz(timestamp, timezone)
.startOf('day')
.toDate()
.getTime();
};
I would like the function 'functionName' to return midnight of America/Los_Angeles time and not in UTC.
The timestamp I entered is 5th May 2017, 11:30 AM UTC.
I expect the function to return me timestamp for 5th May 2017, 00:00 America/Los_Angeles (Since 5th May 2017 11:30 AM UTC will be 11:30 AM -7 hours in America/Los_Angeles.) and convert it to milliseconds.
You have to remove toDate() that gives a JavaScript date object using local time. Then you can use valueOf() instead of getTime().
moment#valueOf simply outputs the number of milliseconds since the Unix Epoch, just like Date#valueOf.
Your code could be like the following:
const functionName = (timestamp, timezone) => {
return moment(timestamp)
.tz(timezone)
.startOf('day')
.valueOf();
};
let timestamp = 1493638245234;
let truncatedTimestamp = functionName(timestamp, 'America/Los_Angeles');
console.log(truncatedTimestamp);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.17/moment-timezone-with-data-2012-2022.min.js"></script>
Note that moment.tz and tz() are equivalent in your case (since you are passing millis).
I modified my function functionName to be like this and it worked.
const functionName = (timestamp, timezone) =>
moment
.tz(timestamp, timezone)
.startOf('day')
.valueOf();
NOTE: Some user posted this answer, but they deleted their answer.
Related
(see this example online: https://stackblitz.com/edit/date-fns-playground-zeitzonen?file=index.ts -> Console output)
Following situation, it is 11:54 AM:
// Setup
const dateString = "2020-08-30T11:54:48.200Z"; // <---- 11:54 AM
const tz = "Europe/Berlin";
const dateFormat = "d. MMM yyyy, E HH:mm";
const dateOptions = { locale: de };
As far as I format the date, it changes its time-zone and adds 2 more hours:
const parsedDate = parseISO(dateString);
const formattedDate = format(parsedDate, dateFormat, dateOptions);
// outputs: 30. Aug 2020, So. 13:54
const zonedDate = utcToZonedTime(dateString, tz);
// outputs: 2020-08-30T11:54:48.200Z
const formattedZonedDate = format(zonedDate, dateFormat, dateOptions);
// outputs: 30. Aug 2020, So. 13:54
The desired (correct) output would be 30. Aug 2020, So. 11:54
Where is my mistake? Does the initial dateString have the correct time zone?
Does the initial dateString have the correct time zone?
Not if you expect it to be in Berlin time, no. The "Z" at the end means "UTC" - so your string represents 11:54 UTC, which would indeed by 13:54 in Berlin. The formatting is doing the right thing in my view.
It's not entirely clear to me why utcToZonedDateTime is still reporting a UTC value rather than the zoned version, admittedly.
If you want dateString to represent a local time, it should probably be "2020-08-30T11:54:48.200". If, on the other hand, you want it to represent a UTC time that is at 11:54 in Berlin, it should be "2020-08-30T09:54:48.200Z" - note the change in hour to 09.
in a project we are using momentjs with date. And from backend we become the date in the following format: 2016-10-19T08:00:00Z (don't ask me why...)
Now we are setting a new date in frontend from some selectboxes. And I am trying to convert this in the same format:
const date = '25.03.2021';
const hour = '13';
const minute = '45'; // this 3 values come from value of selectboxes
const rawDate = moment(date).hour(hour).minute(minute);
// trying to convert to 2021-03-25T13:45:00Z
rawDate.format(); // output: 2021-03-25T13:45:00+00:00
rawDate.format('DD.MM.YYYY hh:mm:ss'); // output: 03.01.2022 08:00:00
rawDate.format('DD.MM.YYYY hh:mm:ss z'); // output: 03.01.2022 08:00:00 UTC
rawDate.format('DD.MM.YYYY hh:mm:ss Z'); // output: 03.01.2022 08:00:00 +00:00
rawDate.toISOString(); // output: 2022-01-03T08:00:00.000Z
I know I could probably just use format() or toISOString() and slice/replace the last bit. But I like to know is there a way without any string concat/manipulation?
You could use moment.utc() to ensure your date is in UTC, then use .format() with the format string DD-MM-YYYYTHH:mm:ss[Z].
I'd also suggest explicity defining the format you are parsing from in the moment() call, e.g. pass 'DD.MM.YYYY' as the second argument.
The reason the backend takes dates in this format is that it's a standardized way of formatting dates to make them machine-readable and consistent (ISO 8601)
const date = '25.03.2021';
const hour = '13';
const minute = '45';
// Raw date will be in the UTC timezone.
const rawDate = moment(date, 'DD.MM.YYYY').hour(hour).minute(minute).utc();
console.log(rawDate.format('DD-MM-YYYYTHH:mm:ss[Z]'));
<script src="https://momentjs.com/downloads/moment.js"></script>
You can try convert to UTC ..?
i.e. Do you intend to make use of a UTC date/time..?
const date = '2021-03-25';
const hour = '13';
const minute = '45'; // this 3 values come from value of selectboxes
const rawDate = moment(date).hour(hour).minute(minute);
const utc = moment.utc(rawDate);
console.log(rawDate.format('DD.MM.YYYY hh:mm:ss'));
console.log(utc.format()); //2021-03-25T11:45:00Z
I'm trying to convert the time ( time alone ) from a known timezone to my local timezone with Moment.js.
I wrote the following function and, I am getting invalidDate as the output.
const convertToLocalTime = (time, tz) => {
const t = moment.tz(time, tz)
const localTime = t.local()
}
time is just time; without any date eg: 10:06 am and,
tz is a timezone string for eg: Europe/Berlin
What am I doing wrong?
See Parsing in Zone:
The moment.tz constructor takes all the same arguments as the moment constructor, but uses the last argument as a time zone identifier.
Since your input (10:06 am) is not in ISO 8601/RFC 2822 recognized format (see moment(String) docs), you have to pass format parameter as shown in moment(String, String).
Here a live sample:
const convertToLocalTime = (time, tz) => {
const t = moment.tz(time, 'hh:mm a', tz)
const localTime = t.local()
return localTime;
}
const res = convertToLocalTime("10:06 am", 'Europe/Berlin');
console.log( res.format('hh:mm a') );
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.14/moment-timezone-with-data-2012-2022.min.js"></script>
I have a list of list of string dates like this: '17/12/2017 19:34'. They are CET dates.
How can I transform it to the user's browser date?
I'm doing this:
const tzGuess = moment.tz.guess()
export const toTimeZone = (time) => {
const format = 'DD/MM/YYYY HH:mm'
return moment(time, format).tz(tzGuess).format(format)
}
console.log(toTimeZone('17/12/2017 19:34', tzGuess))
but how can I say to moment that the date I'm passing at first is a CET one?
Thanks!
You can use moment.tz function for parsing time string using a given timezone (e.g. 'Europe/Madrid').
The issue is: what do you mean with CET? If your input has fixed UTC+1 offset (like Central European Time), then you can use RobG's solution. If you have to consider both CET and CEST, I think that the best soution is to use moment.tz.
Here a live code sample:
const tzGuess = moment.tz.guess()
const toTimeZone = (time) => {
const format = 'DD/MM/YYYY HH:mm'
return moment.tz(time, format, 'Europe/Madrid').tz(tzGuess).format(format)
}
console.log(toTimeZone('17/12/2017 19:34', tzGuess))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js"></script>
A great resource about timezone is the timezone tag info page.
Without moment.js, parse the string to a Date, treating it as UTC, then adjust for the CET offset (+0100). You can then format it using local time values for the client:
// Parse date in format DD/MM/YYYY HH:mm
// Adjust for CET timezone
function parseCET(s) {
var b = s.split(/\D/);
// Subtract 1 from month and hour
var d = new Date(Date.UTC(b[2], b[1]-1, b[0], b[3]-1, b[4]));
return d;
}
var s = '17/12/2017 19:34';
console.log(parseCET(s).toString());
However, if the time needs to observe daylight saving (CEST) for the source time stamp, you'll need to account for that.
Probably and easy answer to this but I can't seem to find a way to get moment.js to return a UTC date time in milliseconds. Here is what I am doing:
var date = $("#txt-date").val(),
expires = moment.utc(date);
Any idea what I am doing wrong?
This is found in the documentation. With a library like moment, I urge you to read the entirety of the documentation. It's really important.
Assuming the input text is entered in terms of the users's local time:
var expires = moment(date).valueOf();
If the user is instructed actually enter a UTC date/time, then:
var expires = moment.utc(date).valueOf();
I use this method and it works. ValueOf does not work for me.
moment.utc(yourDate).format()
As of : moment.js version 2.24.0
let's say you have a local date input, this is the proper way to convert your dateTime or Time input to UTC :
var utcStart = new moment("09:00", "HH:mm").utc();
or in case you specify a date
var utcStart = new moment("2019-06-24T09:00", "YYYY-MM-DDTHH:mm").utc();
As you can see the result output will be returned in UTC :
//You can call the format() that will return your UTC date in a string
utcStart.format();
//Result : 2019-06-24T13:00:00
But if you do this as below, it will not convert to UTC :
var myTime = new moment.utc("09:00", "HH:mm");
You're only setting your input to utc time, it's as if your mentioning that myTime is in UTC, ....the output will be 9:00
This will be the answer:
moment.utc(moment(localdate)).format()
localdate = '2020-01-01 12:00:00'
moment(localdate)
//Moment<2020-01-01T12:00:00+08:00>
moment.utc(moment(localdate)).format()
//2020-01-01T04:00:00Z
moment.utc(date).format(...);
is the way to go, since
moment().utc(date).format(...);
does behave weird...
This worked for me. Others might find it useful.
let date = '2020-08-31T00:00:00Z'
moment.utc(moment(date).utc()).format() // returns 2020-08-30T22:00:00Z
If all else fails, just reinitialize with an inverse of your local offset.
var timestamp = new Date();
var inverseOffset = moment(timestamp).utcOffset() * -1;
timestamp = moment().utcOffset( inverseOffset );
timestamp.toISOString(); // This should give you the accurate UTC equivalent.
This moment.utc(stringDate, format).toDate() worked for me.
This moment.utc(date).toDate() not.
here, I'm passing the date object and converting it into UTC time.
$.fn.convertTimeToUTC = function (convertTime) {
if($(this).isObject(convertTime)) {
return moment.tz(convertTime.format("Y-MM-DD HH:mm:ss"), moment.tz.guess()).utc().format("Y-MM-DD HH:mm:ss");
}
};
// Returns if a value is an object
$.fn.isObject = function(value) {
return value && typeof value === 'object';
};
//you can call it as below
$(this).convertTimeToUTC(date);
Read this documentation of moment.js here.
See below example and output where I convert GMT time to local time (my zone is IST) and then I convert local time to GMT.
// convert GMT to local time
console.log('Server time:' + data[i].locationServerTime)
let serv_utc = moment.utc(data[i].locationServerTime, "YYYY-MM-DD HH:mm:ss").toDate();
console.log('serv_utc:' + serv_utc)
data[i].locationServerTime = moment(serv_utc,"YYYY-MM-DD HH:mm:ss").tz(self.zone_name).format("YYYY-MM-DD HH:mm:ss");
console.log('Converted to local time:' + data[i].locationServerTime)
// convert local time to GMT
console.log('local time:' + data[i].locationServerTime)
let serv_utc = moment(data[i].locationServerTime, "YYYY-MM-DD HH:mm:ss").toDate();
console.log('serv_utc:' + serv_utc)
data[i].locationServerTime = moment.utc(serv_utc,"YYYY-MM-DD HH:mm:ss").format("YYYY-MM-DD HH:mm:ss");
console.log('Converted to server time:' + data[i].locationServerTime)
Output is
Server time:2019-12-19 09:28:13
serv_utc:Thu Dec 19 2019 14:58:13 GMT+0530 (India Standard Time)
Converted to local time:2019-12-19 14:58:13
local time:2019-12-19 14:58:13
serv_utc:Thu Dec 19 2019 14:58:13 GMT+0530 (India Standard Time)
Converted to server time:2019-12-19 09:28:13
This worked for me:
const localtime = 1622516400000
moment(localtime).utc(true).format()
We can get 2 UTC date formats.
const date = '2021-07-20T18:30:00Z';
moment.utc(moment(date).utc()).format(); // 2021-07-19T18:30:00Z
moment.utc(moment(date).utc()).toISOString(); // 2021-07-20T18:30:00.000Z (Complete ISO-8601)
This works in my case.
Library: "moment": "^2.29.1",
moment().utc().format()
Don't you need something to compare and then retrieve the milliseconds?
For instance:
let enteredDate = $("#txt-date").val(); // get the date entered in the input
let expires = moment.utc(enteredDate); // convert it into UTC
With that you have the expiring date in UTC.
Now you can get the "right-now" date in UTC and compare:
var rightNowUTC = moment.utc(); // get this moment in UTC based on browser
let duration = moment.duration(rightNowUTC.diff(expires)); // get the diff
let remainingTimeInMls = duration.asMilliseconds();