कैसे आईएसओ 8601 जावास्क्रिप्ट में Timezone ऑफसेट के साथ एक तारीख प्रारूप?


100

लक्ष्य: निम्नलिखित स्वरूप में URL का पता लगाएं local timeऔर UTC time offsetफिर निर्माण करें।

उदाहरण URL: / क्रियाएँ / नींद? अवधि = 2002-10-10T12: 00: 00505: 00

प्रारूप W3C अनुशंसा पर आधारित है: http://www.w3.org/TR/xmlschema11-2/#dateTime

प्रलेखन कहता है:

उदाहरण के लिए, 2002-10-10T12: 00: 00505: 00 (10 अक्टूबर 2002 को दोपहर, केंद्रीय डेलाइट बचत का समय और साथ ही पूर्वी मानक समय अमेरिका में) 2002-10-10T17: 00: 00Z, के बराबर है पांच घंटे बाद 2002-10-10T12: 00: 00Z।

इसलिए मेरी समझ के आधार पर, मुझे अपना स्थानीय समय नई तिथि () के द्वारा खोजना होगा, फिर अंतर को गणना करने के लिए getTimezoneOffset () फ़ंक्शन का उपयोग करें और फिर इसे स्ट्रिंग के अंत में संलग्न करें।

1. प्रारूप के साथ स्थानीय समय निर्धारित करें

var local = new Date().format("yyyy-MM-ddThh:mm:ss"); //today (local time)

उत्पादन

2013-07-02T09:00:00

2. समय यूटीसी समय ऑफसेट घंटे

var offset = local.getTimezoneOffset() / 60;

उत्पादन

7

3. URL का निर्माण (केवल समय भाग)

var duration = local + "-" + offset + ":00";

उत्पादन:

2013-07-02T09:00:00-7:00

उपरोक्त आउटपुट का मतलब है मेरा स्थानीय समय 2013/07/02 9am है और UTC से अंतर 7 घंटे (UTC स्थानीय समय से 7 घंटे आगे है)

अब तक यह काम करने लगता है, लेकिन क्या होगा अगर getTimezoneOffset () -120 की तरह नकारात्मक मूल्य लौटाता है?

मैं सोच रहा हूं कि ऐसे मामले में प्रारूप कैसा दिखना चाहिए क्योंकि मैं डब्ल्यू 3 सी दस्तावेज का पता नहीं लगा सकता। अग्रिम में धन्यवाद।

जवाबों:


174

नीचे ठीक से काम करना चाहिए, और सभी ब्राउज़रों के लिए (टिप के लिए @MattJohnson को धन्यवाद)

Date.prototype.toIsoString = function() {
    var tzo = -this.getTimezoneOffset(),
        dif = tzo >= 0 ? '+' : '-',
        pad = function(num) {
            var norm = Math.floor(Math.abs(num));
            return (norm < 10 ? '0' : '') + norm;
        };
    return this.getFullYear() +
        '-' + pad(this.getMonth() + 1) +
        '-' + pad(this.getDate()) +
        'T' + pad(this.getHours()) +
        ':' + pad(this.getMinutes()) +
        ':' + pad(this.getSeconds()) +
        dif + pad(tzo / 60) +
        ':' + pad(tzo % 60);
}

var dt = new Date();
console.log(dt.toIsoString());


2
संकेत GMT से स्थानीय समय की ऑफसेट को इंगित करता है
स्टीवन मोसले

1
@ masato- सान आपको साइन
इनवर्ट करना है

2
यहां पैड फ़ंक्शन मिलिसकंड को छोड़कर तारीख के प्रत्येक खंड के लिए उचित स्ट्रिंग देता है। उदाहरण के लिए, एक इनपुट के रूप में 5ms के लिए 05 लौट आएगा, जो 005 माना जाता है। यहाँ एक ही फ़ंक्शन के न्यूनतम संशोधित संस्करण के साथ लिंक दिया गया है jsbin
Safique Ahmed Faruque

9
कृपया ध्यान दें: इस उत्तर में एक सूक्ष्म बग है। यदि ज़ोन में ऑफ़सेट मिनट्स थे और टाइम नेगेटिव था (जैसे -09: 30), तो टाइमज़ोन ऑफ़सेट्स की सही गणना नहीं की जाएगी, जैसे कि फ्रांस और कनाडा के कुछ निश्चित स्थान। मॉड एक नकारात्मक संख्या देता है, इसलिए एब्स () से पहले फर्श () को अनजाने में ऑफसेट को और अधिक नकारात्मक बना दिया जाता है। इस बग को ठीक करने के लिए, एब्स () और THEN फ्लोर ()। उत्तर को संपादित करने की कोशिश की, लेकिन जाहिरा तौर पर "इस संपादन का उद्देश्य पोस्ट के लेखक को संबोधित करना था और एक संपादन के रूप में कोई मतलब नहीं है"।
tytk

5
@tytk - शानदार कैच! वह है, वास्तव में, सूक्ष्म। मैंने जवाब में आपका फिक्स जोड़ दिया। टिप्पणी करने के लिए धन्यवाद!
स्टीवन मोसले

67

getTimezoneOffset() आपके द्वारा संदर्भित युक्ति द्वारा आवश्यक प्रारूप के विपरीत संकेत देता है।

इस प्रारूप को ISO8601 के रूप में भी जाना जाता है , या अधिक सटीक रूप से RFC3339 के रूप में जाना जाता है ।

इस प्रारूप में, UTC का प्रतिनिधित्व किया जाता है, Zजबकि अन्य सभी स्वरूपों को UTC से ऑफसेट द्वारा दर्शाया जाता है। अर्थ जावास्क्रिप्ट के समान है, लेकिन घटाव का क्रम उल्टा है, इसलिए परिणाम विपरीत संकेत ले जाता है।

इसके अलावा, देशी Dateवस्तु पर कोई विधि नहीं है format, इसलिए # 1 में आपका फ़ंक्शन तब तक विफल रहेगा जब तक कि आप इसे प्राप्त करने के लिए लाइब्रेरी का उपयोग नहीं कर रहे हैं। इस प्रलेखन का संदर्भ लें ।

यदि आप एक पुस्तकालय की मांग कर रहे हैं जो इस प्रारूप के साथ सीधे काम कर सकता है, तो मैं क्षण भर की कोशिश कर रहा हूं । वास्तव में, यह डिफ़ॉल्ट प्रारूप है, इसलिए आप बस ऐसा कर सकते हैं:

var m = moment();    // get "now" as a moment
var s = m.format();  // the ISO format is the default so no parameters are needed

// sample output:   2013-07-01T17:55:13-07:00

यह एक अच्छी तरह से परीक्षण किया गया, क्रॉस-ब्राउज़र समाधान है, और इसमें कई अन्य उपयोगी विशेषताएं हैं।


का उपयोग कर toISOString () काम नहीं करेगा। +01: 00 प्रारूप में स्थानीय समय के भाग की आवश्यकता होती है। toISOString () एक UTC टाइम स्ट्रिंग देगा।
ऑस्टिन फ्रांस

1
@AustinFrance - आप सही कह रहे हैं! मुझे आश्चर्य है कि मैंने उस समय यह गलती की, क्योंकि मैं अक्सर इस बिंदु पर दूसरों को सही करता हूं। क्षमा करें, मैंने दो साल पहले आपकी टिप्पणी नहीं देखी थी! उत्तर संपादित किया गया।
मैट जॉनसन-पिंट

9

मुझे लगता है कि यह विचार करने योग्य है कि आप मानक पुस्तकालय में केवल एक एपीआई कॉल के साथ अनुरोधित जानकारी प्राप्त कर सकते हैं ...

new Date().toLocaleString( 'sv', { timeZoneName: 'short' } );

// produces "2019-10-30 15:33:47 GMT−4"

यदि आपको 'T' सीमांकक जोड़ना है, तो 'GMT-' को हटाना है, या अंत में ': 00' को जोड़ना है।

लेकिन फिर आप चाहें तो अन्य विकल्पों के साथ आसानी से खेल सकते हैं । 12h समय का उपयोग करें या सेकंड आदि को छोड़ें

ध्यान दें कि मैं स्वीडन को लोकेल के रूप में उपयोग कर रहा हूं क्योंकि यह उन देशों में से एक है जो आईएसओ 8601 प्रारूप का उपयोग करता है। मुझे लगता है कि ज्यादातर आईएसओ देश टाइमजोन ऑफसेट के लिए इस 'GMT-4' प्रारूप का उपयोग करते हैं फिर कनाडा जो समय क्षेत्र संक्षिप्त नाम उदा का उपयोग करता है। पूर्वी-दिन के समय के लिए "ईडीटी"।

आप नए मानक i18n फ़ंक्शन "Intl.DateTimeFormat ()" से एक ही चीज़ प्राप्त कर सकते हैं, लेकिन आपको इसे विकल्पों के माध्यम से समय शामिल करने के लिए बताना होगा या यह सिर्फ तारीख देगा।


1
Hm, sv के लिए, मुझे वास्तव में "CET" मिलता है और एक समर टाइम डेट, "CEST" के लिए ... लेकिन इनपुट के लिए धन्यवाद, मेरे लिए मानक API पर्याप्त है (एक तारीख के साथ लॉग संदेशों को उपसर्ग करने की आवश्यकता है)। अगर मैं समय और समय के बारे में गंभीर होना चाहता था, मुझे लगता है कि मैं पल पुस्तकालय के लिए जाना होगा ...
21

4

यह ग्राहकों के लिए मेरा कार्य समय क्षेत्र है, यह लाइट वेट और सरल है

  function getCurrentDateTimeMySql() {        
      var tzoffset = (new Date()).getTimezoneOffset() * 60000; //offset in milliseconds
      var localISOTime = (new Date(Date.now() - tzoffset)).toISOString().slice(0, 19).replace('T', ' ');
      var mySqlDT = localISOTime;
      return mySqlDT;
  }

@tsh, क्या आपको यकीन है? आपको वर्तमान समय की भरपाई हो रही है, जिसे बाद में स्थानीय समय का अनुकरण करने के लिए उपयोग किया जाता है। हो सकता है कि उस बिंदु पर ऑफसेट अलग था, लेकिन इससे कोई फर्क नहीं पड़ता क्योंकि आप अभी के बारे में परवाह करते हैं।
एंड्रयू

2

इसे देखो:

function dateToLocalISO(date) {
    const off    = date.getTimezoneOffset()
    const absoff = Math.abs(off)
    return (new Date(date.getTime() - off*60*1000).toISOString().substr(0,23) +
            (off > 0 ? '-' : '+') + 
            (absoff / 60).toFixed(0).padStart(2,'0') + ':' + 
            (absoff % 60).toString().padStart(2,'0'))
}

// Test it:
d = new Date()

dateToLocalISO(d)
// ==> '2019-06-21T16:07:22.181-03:00'

// Is similar to:

moment = require('moment')
moment(d).format('YYYY-MM-DDTHH:mm:ss.SSSZ') 
// ==> '2019-06-21T16:07:22.181-03:00'

1

कोई भी क्षण की आवश्यकता नहीं है: यहां "डेटाइम-लोकल" के एक इनपुट प्रकार से एक पूर्ण दौर की यात्रा का उत्तर दिया गया है, जो जीएमटी और बैक में यूटीसीसेकंड के लिए एक ISOLocal स्ट्रिंग को आउटपुट करता है:

<input type="datetime-local" value="2020-02-16T19:30">

isoLocal="2020-02-16T19:30"
utcSeconds=new Date(isoLocal).getTime()/1000

//here you have 1581899400 for utcSeconds

let isoLocal=new Date(utcSeconds*1000-new Date().getTimezoneOffset()*60000).toISOString().substring(0,16)
2020-02-16T19:30

0

बस मेरे दो यहाँ भेजता है

मैं इस मुद्दे का सामना कर रहा था datetimes के साथ तो मैंने क्या किया यह है:

const moment = require('moment-timezone')

const date = moment.tz('America/Bogota').format()

फिर कुछ क्वेरी से तुलना करने में सक्षम होने के लिए डीबी को तारीख सहेजें।


स्थापित करने के लिए moment-timezone

npm i moment-timezone

0

मेरा जवाब उन लोगों के लिए एक मामूली बदलाव है, जो अभी YYYY-MM-DD प्रारूप में स्थानीय समयक्षेत्र में आज की तारीख चाहते हैं।

मुझे स्पष्ट होने दो:

मेरे लक्ष्य: प्राप्त आज की तारीख में उपयोगकर्ता के समय क्षेत्र लेकिन ISO8601 के रूप में स्वरूपित (YYYY-MM-DD)

यहाँ कोड है:

new Date().toLocaleDateString("sv") // "2020-02-23" // 

यह काम करता है क्योंकि स्वीडन लोकेल आईएसओ 8601 प्रारूप का उपयोग करता है।


अमान्य उत्तर, यह उत्तर देता है, लेकिन अन्य प्रश्न ... यह उत्तर SO पर आसानी से पाया जा सकता है।
साइकोक्स

0

इस कार्य को मैंने इस अंत के लिए उपयोग किया है:

function localToGMTStingTime(localTime = null) {
    var date = localTime ? new Date(localTime) : new Date();
    return new Date(date.getTime() + (date.getTimezoneOffset() * 60000)).toISOString();
};

function GMTToLocalStingTime(GMTTime = null) {
    var date = GMTTime ? new Date(GMTTime) : new Date();;
    return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString();
};

0

आप इसे कुछ सरल एक्सटेंशन विधियों के साथ प्राप्त कर सकते हैं। निम्न दिनांक विस्तार विधि आईएसओ प्रारूप में सिर्फ टाइमजोन घटक देता है, फिर आप दिनांक / समय भाग के लिए एक और परिभाषित कर सकते हैं और उन्हें पूर्ण तिथि-समय-ऑफसेट स्ट्रिंग के लिए जोड़ सकते हैं।

Date.prototype.getISOTimezoneOffset = function () {
    const offset = this.getTimezoneOffset();
    return (offset < 0 ? "+" : "-") + Math.floor(Math.abs(offset / 60)).leftPad(2) + ":" + (Math.abs(offset % 60)).leftPad(2);
}

Date.prototype.toISOLocaleString = function () {
    return this.getFullYear() + "-" + (this.getMonth() + 1).leftPad(2) + "-" +
        this.getDate().leftPad(2) + "T" + this.getHours().leftPad(2) + ":" +
        this.getMinutes().leftPad(2) + ":" + this.getSeconds().leftPad(2) + "." +
        this.getMilliseconds().leftPad(3);
}

Number.prototype.leftPad = function (size) {
    var s = String(this);
    while (s.length < (size || 2)) {
        s = "0" + s;
    }
    return s;
}

उदाहरण का उपयोग:

var date = new Date();
console.log(date.toISOLocaleString() + date.getISOTimezoneOffset());
// Prints "2020-08-05T16:15:46.525+10:00"

मुझे पता है कि यह 2020 है और ज्यादातर लोग अब तक Moment.js का उपयोग कर रहे हैं, लेकिन एक सरल कॉपी और पेस्ट करने योग्य समाधान अभी भी कभी-कभी काम में आता है।

(जिस कारण से मैंने तिथि / समय और ऑफ़सेट विधियों को विभाजित किया है, क्योंकि मैं एक पुरानी डेटज लाइब्रेरी का उपयोग कर रहा हूं जो पहले से ही toStringकस्टम प्रारूप विनिर्देशकों के साथ एक लचीली विधि प्रदान करता है , लेकिन इसमें टाइमज़ोन ऑफसेट शामिल नहीं है। इसलिए, मैंने toISOLocaleStringबिना किसी के लिए जोड़ा। पुस्तकालय कहा।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.