JsLearner
JsLearner

Reputation: 109

How do I convert local time to UTC?

I want to convert my local time (shown below) to UTC. Local time can belong to any timezone which a user belongs to. I just want to convert it to UTC format.

Local Time : '2015-12-04 19:05:48'

How do I achieve this requirement in JavaScript or AngularJS?


Update

My Original date/time string as like this "Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)" and I have converted them to "2016-03-28 23:59:59 CDT" as requested date format. But again, I need to convert this interim output in to UTC in the same interim output format "YYYY-MM-DD HH:MM:SS". How do I achieve this

Upvotes: 2

Views: 12601

Answers (3)

lechat
lechat

Reputation: 467

You can try this.
fiddle: https://jsfiddle.net/shuNaka/v891skuh/

const datetime = "2020-02-12 10:30:00";
const timezone = "Asia/Tokyo";

document.getElementById("localtime").innerHTML = datetime;
document.getElementById("timezone").innerHTML = timezone;
document.getElementById("utctime").innerHTML = getUtcFromLocaltime(datetime, timezone);

function getUtcFromLocaltime (localtimeString, timezone) {
    // Change it to moment object
    const localTime = moment(localtimeString, 'YYYY-MM-DD HH:mm:ss', true);
    // Get the timezone
    const timeDiff  = moment().tz(timezone).format('ZZ')
    // Get the time difference
    let numTimeDiff = Number(timeDiff.substr(1)) / 100;
    numTimeDiff = hourAdjust(numTimeDiff);
    // Get UTC from the timezone(+0900)
    if (timeDiff.charAt(0) === '+') {
        return localTime.subtract({hours: numTimeDiff}).format('YYYY-MM-DD HH:mm:ss');
    } else if (timeDiff.charAt(0) === '-') {
        return localTime.add({hours: numTimeDiff}).format('YYYY-MM-DD HH:mm:ss');
    }
}


function hourAdjust (hour) {
    let mhour = Math.floor(hour);
    let min = (Math.floor(hour * 100) % 100) / 6;
    return Number(mhour+"."+min);
}

Upvotes: 1

RobG
RobG

Reputation: 147503

The first step is to parse your original string. Do not remove the timezone offset since timezone names are not standardised, nor are their abbreviations. To parse "Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)" you can use a function like the following.

You can then format a string based on the date, but you must keep the timezone as a string like "2016-03-29 05:59:59" will be treated as local by any implementation that is vaguely consistent with ISO 8601.

In most cases, "2016-03-29 05:59:59Z" will be treated as UTC as the joining "T" can be omitted by agreement (per ISO 8601).

// Parse date string in format:
// "Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)"
function parseDate(s) {
  var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5,
                jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};
  var b = s.split(/[\s:]/);
  // Calc offset in minutes
  // JS offsets are opposite sense to everyone else
  var offset = (b[8] < 0? 1 : -1) * (b[8].slice(1,3)*60 + +b[8].slice(-2));
  // Create UTC date
  return new Date(Date.UTC(b[3], months[b[1].toLowerCase().substr(0,3)],
                            b[2], b[4], +b[5] + offset, b[6]));
} 

// Format date as yyyy-mm-dd hh:mm:ssZ
// The timezone really should be included as this string will
// be treated as local if ISO 8601 rules are used (and the commonly are)
function formatDate(d) {
  function z(n){return (n<10?'0':'')+n}
  return d.getUTCFullYear() + '-' +
         z(d.getUTCMonth() + 1) + '-' +
         z(d.getUTCDate()) + ' ' +
         z(d.getUTCHours()) + ':' +
         z(d.getUTCMinutes()) + ':' +
         z(d.getUTCSeconds()) + 'Z';
}

var s = 'Mon March 28 2016 23:59:59 GMT -0600 (CENTRAL DAYLIGHT TIME)';
var d = parseDate(s);

document.write('<br>Original: ' + s + '<br>' +
               'Local   : ' + d + '<br>' + 
               'UTC     : ' + formatDate(d) + '<br>' +
               'ISO 8601: ' + d.toISOString());
body {
  font-family: courier, monospace;
  font-size: 75%;
  white-space: pre;
}

Upvotes: 0

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48723

You can create a new local date based on the UTC values of the original (local) date.

var localDate = parseDate('2015-12-04 19:05:48 CDT'); // With or without CDT (still works)

document.body.innerHTML  = [
  '- Local Time: ' + formatDate(localDate),
  '-   UTC Time: ' + formatDate(localDateToUTC(localDate))
].join('\n');

function parseDate(dateString) {
  var tokens = dateString.split(/[-: ]/g).slice(0, 6).map(function(token) { return parseInt(token, 10); });
  tokens[1] -= 1; // Subtract 1 from month.
  return newInstance(Date, tokens);
}

function formatDate(date) {
  function pad(val, pattern) { return (pattern + val).substr(-pattern.length); } 
  return date.getFullYear() + '-' + pad(date.getMonth() + 1, '00') + '-' + pad(date.getDate(), '00') + ' ' +
    pad(date.getHours(), '00') + ':' + pad(date.getMinutes(), '00') + ':' + pad(date.getSeconds(), '00');
}

function localDateToUTC(localDate) {
  return new Date(localDate.getUTCFullYear(), localDate.getUTCMonth(), localDate.getUTCDate(),
                  localDate.getUTCHours(), localDate.getUTCMinutes(), localDate.getUTCSeconds());
}

function newInstance(clazz, arguments, scope) {
  return new (Function.prototype.bind.apply(clazz, [scope].concat(arguments)));
}
body {
  font-family: monospace;
  white-space: pre;
}

Upvotes: 0

Related Questions