Junaid Farooq
Junaid Farooq

Reputation: 2608

Converting datetime timezone in JavaScript

I have this date "2021-06-13T08:10:27.00013004+08:00" in the Asia/Singapore timezone.

I want to convert it into Etc/UTC timezone and I am doing this approach.

var year = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, year: 'numeric'});
var month = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, month: '2-digit'});
var day = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, day: '2-digit'});
var hour = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, hour: '2-digit'});
var minute = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, minute: '2-digit'});
var second = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, second: '2-digit'});

I know this is not really efficient but working to some extent, I am doing it in Google Apps script.

but the issue is for the above date, my conversion is giving me.

2021/06/13/24 10_27_000

this date. which is not even possible? It should results into

2021/06/13/23 10_27_000

in 23 hours instead of 24. Can you please help me with this?

I want to convert Asia/Singapore timezone to Etc/UTC, for more details. I have this filename ShawTower__2021-06-13-08-10-27_00013004.jpg from which I am extracting the data as

var timestamp = filename.match(/\d+/g).map(String);
var actualDate = "" + timestamp[0] + "-" + timestamp[1] + "-" + timestamp[2] + "T" + timestamp[3] + ":" + timestamp[4] + ":" + timestamp[5] + "." + timestamp[6] + "+08:00";

is it possible in plain JS so

  1. Attach a timezone to DateTime (not convert at first)
  2. Convert it to another timezone

any help would be wonderful thank you.

Upvotes: 0

Views: 980

Answers (3)

Yuri Khristich
Yuri Khristich

Reputation: 14527

Are you sure that 00 or 24 hours is not even possible for your date? It looks like JS, GAS and Python assume that there should be 00 or 24.

JS:

var actualDate = "2021-06-13T08:10:27.00013004+08:00";

var year   = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, year:   'numeric'});
var month  = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, month:  '2-digit'});
var day    = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, day:    '2-digit'});
var hour   = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, hour:   '2-digit'});
var minute = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, minute: '2-digit'});
var second = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, second: '2-digit'});

var str = [year, month, day, hour].join("/") + " " + [minute, second, "000"].join("_");

console.log(str); // output: 2021/06/13/00 10_27_000

GAS:

function myFunction() {

  var actualDate = "2021-06-13T08:10:27.00013004+08:00";

  var year   = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, year:   'numeric'});
  var month  = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, month:  '2-digit'});
  var day    = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, day:    '2-digit'});
  var hour   = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, hour:   '2-digit'});
  var minute = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, minute: '2-digit'});
  var second = new Date(actualDate).toLocaleString("en-US", {timeZone: "Etc/UTC", hour12: false, second: '2-digit'});

  var str = year + "/" + month + "/" + day + "/" + hour + " " + minute + "_" + second + "_000"

  Logger.log(str); // output: 2021/06/13/24 10_27_000

}

Python:

from datetime import datetime
import pytz

date = datetime.fromisoformat('2021-06-13T08:10:27+08:00')
local_date = date.astimezone(pytz.timezone('Etc/UTC'))
print(local_date.strftime('%Y/%m/%d/%H %M_%S_000')) # output: 2021/06/13/00 10_27_000

Update

Based on @doubleunary answer, another GAS implementation, which gives the same 24 hours:

function main() {
  const date = new Date('2021-06-13T08:10:27.00013004+08:00');
  const timezone = 'UTC';
  const dateString = Utilities.formatDate(date, timezone, 'yyyy/MM/dd/kk mm_ss_000');

  Logger.log(dateString); // output: 2021/06/13/24 10_27_000
}

Upvotes: 0

doubleunary
doubleunary

Reputation: 18784

JavaScript Date objects are always in the UTC timezone. To display a date in a particular timezone using Apps Script, use this pattern:

function testUtcDateString() {
  const filename = 'ShawTower__2021-06-13-08-10-27_00013004.jpg';
  console.log(getUtcDateString_(filename));
}

function getUtcDateString_(filename) {
  const fromTimezone = '+08:00';
  const toTimezone = 'UTC';
  const dateString = filename.replace(/^.*(\d\d\d\d-\d\d-\d\d)-(\d\d)-(\d\d)-(\d\d).*$/, '$1T$2:$3:$4') + fromTimezone;
  return Utilities.formatDate(new Date(dateString), toTimezone, 'yyyy-MM-dd hh:mm:ss');
}

Note that you may need to use a different value for the +08:00 bit, depending on the timezone of your script project. You can get the script timezone with Session.getScriptTimeZone().

To get the result string in another format, use a different format pattern. See Utilities.formatDate().

Upvotes: 2

Vuk
Vuk

Reputation: 873

MomentJs is a great library for formatting and super simple to use: https://momentjs.com/docs/#/parsing/string-format/

Example

const formattedDateTime = moment(dateTime, currentFormat).format(newFormat);

See their documentation for the correct formatting strings

Upvotes: 0

Related Questions