How to change timezone without changing time? - node.js

I have a node.js application using Typescript and prisma as an ORM for postgresql.
I am using dayjs but can use native time methods.
I have an api that returns sales date at this format "2022-09-27 16:54:13" it has no information about the timezone but I know it is in the store timezone
I can access the store timezone by querying a different endpoint. What I would like to do is store this date as a timestamp with timezone in postgresql. So I need to be able to keep the datetime as is but change the timezone.
So "2022-09-27 16:54:13" needs to become "2022-09-27 16:54:13+02" if the store's timezone is "Europe/Paris" during DST for example.
I tried to use dayjs with the utc and tz plugins but I can not make it work. Here is what I tried :
import utc from "dayjs/plugin/utc.js";
import timezone from "dayjs/plugin/timezone.js";
dayjs.extend(utc);
dayjs.extend(timezone);
const date = dayjs("2020-09-21 20:30");
// Mon Sep 21 2020 20:30:00 GMT+0200
const date2 = date.tz("Asia/Jakarta")
// Mon Sep 21 2020 20:30:00 GMT+0200
const date3 = date.tz("Asia/Jakarta", true)
// Mon Sep 21 2020 15:30:00 GMT+0200
dayjs.tz.setDefault("Asia/Jakarta");
console.log(dayjs.tz(date).toDate())
// Mon Sep 21 2020 20:30:00 GMT+0200
I tried using native time methods but no matter what I try it either converts but keep the local timezone or don't change anything altogether
Is there any way to get a correct timestamp with the correct timezone ?

Related

How to parse String to DateTime using ParseExact [duplicate]

I'm using RSS feeds from multiple sources and I'm sorting the feeds by date. However, the dates I receive are in different time zones.
This is the format of some of the date strings that I get:
Wed 08 Dec 2021 01:40:31 -0500
Wed 08 Dec 2021 11:11:19 -0600
The "-500' indicates the time zone which is UTC-5. I need to use that "-0500" to convert this string into a date and the date needs to be only in UTC.
Basically from "Wed 08 Dec 2021 01:40:31 -0500" to "12/08/2021 06:40:31"
I've managed to split the string up to sort by date but because of the time difference, it doesn't really help.
Is there coding which I can use to convert the string as-is into date and only UTC time? Or is there just a place where I can start?
Thank you in advance.
Using DateTime.ParseExact, you specify a format to convert from, and that can include "zzz" for the timezone offset. You can also specify that you want the result in UTC:
Dim s = "Wed 08 Dec 2021 01:40:31 -0500"
Dim d = DateTime.ParseExact(s, "ddd dd MMM yyyy HH:mm:ss zzz", Nothing, Globalization.DateTimeStyles.AdjustToUniversal)
Console.WriteLine(d.ToString("yyyy-MM-dd HH:mm:ss"))
Console.WriteLine(d.Kind.ToString())
Outputs:
2021-12-08 06:40:31
Utc
Of course, format the result as you desire.
Alternatively, if you need to, you can keep the offset by using a DateTimeOffset structure and adjust it to UTC for representation as a string:
Dim s = "Wed 08 Dec 2021 01:40:31 -0500"
Dim d = DateTimeOffset.ParseExact(s, "ddd dd MMM yyyy HH:mm:ss zzz", Nothing)
Console.WriteLine(d.ToUniversalTime.ToString("yyyy-MM-dd HH:mm:ss"))
Outputs:
2021-12-08 06:40:31

Doing {a time between midnight and 1am} .isBefore {a time later that day} is coming up FALSE (it seems) - using moment-timezone

I'm trying to replicate a bug. Essentially, I've got the code below in an app. It works here i.e. 'midnight is before 7am' is true.
// The server is running in UTC
const moment = require("moment-timezone");
moment.tz.setDefault("Europe/London");
const now = moment("2020-04-20 00:00"); // In the app, 'now' is the current moment()
const testTime = "07:00", testTimeMoment = moment(testTime, "HH:mm");
console.log(`now: ${now}\nUTC: ${now.utc()}\ntestTime: ${testTimeMoment}`);
console.log(`'now' is before 'testTime' ? ${now.isBefore(testTimeMoment)}`);
The console.log is:
now: Mon Apr 20 2020 00:00:00 GMT+0100
UTC: Sun Apr 19 2020 23:00:00 GMT+0000
testTime: Mon Apr 20 2020 07:00:00 GMT+0100
'now' is before 'testTime' ? true
But in my app this test seems to fail, until you get to 1am and later, and then the comparison becomes true.
My server here in the UK is running on UTC/GMT. But we're on daylight saving time, so I'm defaulting to London time.
Any ideas?
UPDATE: The comparison operator is actually behaving correctly. It's not giving the expected result because, between midnight and 1am, the testTime moment is created as 7am the day before. It's 7am British Summer Time as I want it, because of setting the default timezone at the top of the code, but the day before. After 1am, the moment is correctly created as 7am today.

NodeJS Date parsing "old" rfc1123 dates incorrectly

I have an RFC1123 Date string, such as: 'Mon, 01 Jan 0001 00:00:01 GMT'
I want to parse this string into a Date in NodeJS. I assumed that new Date('Mon, 01 Jan 0001 00:00:01 GMT') would achieve what I wanted... but it doesn't. When I inspect the content of the resultant Date I see that .toUTCString() gives Mon, 01 Jan 2001 00:00:01 GMT.
I am at a loss as to how the parsing function determined that the year was 2001.
What's even more bizarre is that if I use ISO8601 format instead, and do: new Date('0001-01-01T00:00:01Z').toUTCString() I get Mon, 01 Jan 1 00:00:01 GMT -- exactly what I would expect -- yet if I then do new Date('Mon, 01 Jan 1 00:00:01 GMT') I still get the year as 2001.
Note: I can process these same strings in another language (C#) and I get exactly what I would expect.
Anybody have any suggestions for how to correctly deserialize RFC1123 Date's in NodeJS? If the date is "new" (i.e. above the year 1000) things seem to work okay, but "old" dates seem broken, or else I'm missing something "extra" which is required for older dates.
edit: It looks like technically the RFC 1123/2822 format has a lower bound of the year 1900 -- although Date allows us to go below that so I am not sure what's stopping it from supporting years <100.
You could use moment.js to parse the date:
var dateFormat = 'ddd, DD MMM YYYY HH:mm:ss',
dateString = 'Mon, 01 Jan 0001 00:00:01 GMT';
var dateTime = moment.utc(dateString, dateFormat);

How to convert time format from Moment to D3?

In Node, I am using Moment for time and on the front-end I am using the D3 package. For moment, I will get a time of 1429588800 which is converts to "Tue Apr 21 2015 00:00:00 GMT-0400". But in D3, I get "05/031976". This is with the format "%x".
The problem I believe is that you use seconds (unix timestamp). If you multiply it by 1000 it should work. Here are some tests for you
var value = 1429588800;
var f = d3.time.format("%x");
var date = new Date(value*1000);
var moment_date = moment.unix(value);
console.log('date',date); //date Tue Apr 21 2015 00:00:00 GMT-0400 (Eastern Daylight Time)
console.log('moment date',moment_date.format()); //moment date 2015-04-21T00:00:00-04:00
console.log('d3 + moment date',f(moment_date.toDate())); //d3 + moment date 04/21/15
console.log('d3 + date',f(date)); //d3 + date 04/21/15

Mongoose Update Condition PDT Date/ Model ISO Date

Hi my Schmema has a field with an ISO-Date:
ISODate("2015-04-30T14:47:46.501Z")
Paypal returns on a successful payment a date object in that form:
Time/Date stamp generated by PayPal, in the following format: HH:MM:SS Mmm DD, YYYY PDT
Length: 28 characters
Now I want to update the database entry which has the payers_email_address and a timestamp which does maximum differ from paypals timestamp by 15min.
These are the steps I think are necessary to do this:
1) On this step I'm not sure. The blunt way would be to Stringify the paypal date and then to split it and rearrange it. But I guess there is a better way?
Question: How to convert the PDT date properly into the UTC date.
2) Make a new UTC date:
var dt = new Date('2010-06-09T15:20:00Z');
3)
Add 15 min to the date:
dt.setMinutes (dt.getMinutes() + 15);
4) Query inbetween two dates
MongoDB/Mongoose querying at a specific date?
In whole (does not work for a date on 30/04/2015)
MyModel.find({date: {"$gte": new Date("10:00:46 04 29, 2015").toUTCString(), "$lt": new Date("14:00:46 05 01, 2015").toUTCString()}})
EDIT:
I guess if I got the query bove working I can just use the same with PDT:
new Date("20:15:10 05 10, 1985 PDT").toUTCString()
I posted my steps because maybe there is mongoose function for converting the date and I don't have to do 1-3.
This works in my mongoShell I will report later if it worked in the program:
MyModel.find({date: {"$gte": new Date("10:00:46 04 29, 2015 PDT"), "$lt": new Date("14:00:46 05 01, 2015 PDT")}})

Resources