UTC के कारण JSON तारीख के समय में परिवर्तन करता है


98

जावास्क्रिप्ट में मेरी तारीख की वस्तुओं को हमेशा यूटीसी +2 द्वारा दर्शाया जाता है क्योंकि मैं जहां स्थित हूं। इसलिए इस तरह

Mon Sep 28 10:00:00 UTC+0200 2009

समस्या JSON.stringifyऊपर की तारीख को एक धर्मान्तरित कर रही है

2009-09-28T08:00:00Z  (notice 2 hours missing i.e. 8 instead of 10)

मुझे सम्मानित होने की तारीख और समय की आवश्यकता है, लेकिन यह नहीं है, इसलिए यह होना चाहिए

2009-09-28T10:00:00Z  (this is how it should be)

मूल रूप से मैं इसका उपयोग करता हूं:

var jsonData = JSON.stringify(jsonObject);

मैंने एक प्रतिकृति पैरामीटर (स्ट्रिंग पर दूसरा पैरामीटर) पारित करने की कोशिश की, लेकिन समस्या यह है कि मूल्य पहले ही संसाधित हो चुका है।

मैं भी उपयोग करने की कोशिश toString()और toUTCString()तारीख वस्तु पर है, लेकिन इन मुझे देना नहीं है कि मैं क्या या तो चाहते हैं ..

क्या कोई मेरी मदद कर सकता है?


17
2009-09-28T10:00:00Z समय के रूप में उसी क्षण का प्रतिनिधित्व नहीं करता हैMon Sep 28 10:00:00 UTC+0200 2009Zएक में आईएसओ 8601 की तारीख यूटीसी का मतलब है, और यूटीसी में 10 बजे के समय में एक अलग पल 0200 में 10 बजे। तारीख को सही समय क्षेत्र के साथ क्रमबद्ध करना चाहते हैं, यह एक बात होगी, लेकिन आप हमें इसे एक प्रतिनिधित्व के लिए अनुक्रमित करने में मदद करने के लिए कह रहे हैं जो कि असमान रूप से, निष्पक्ष रूप से गलत है
मार्क अमेरी

1
Marks टिप्पणी में जोड़ने के लिए, ज्यादातर मामलों में अपने डेटासेट को UTC समय के रूप में संग्रहीत करना सबसे अच्छा अभ्यास है, इसलिए आप उपयोगकर्ताओं को अलग-अलग
टाइमज़ोन

जवाबों:


67

हाल ही में मैं इसी मुद्दे पर चला हूं। और यह निम्नलिखित कोड का उपयोग करके हल किया गया था:

x = new Date();
let hoursDiff = x.getHours() - x.getTimezoneOffset() / 60;
let minutesDiff = (x.getHours() - x.getTimezoneOffset()) % 60;
x.setHours(hoursDiff);
x.setMinutes(minutesDiff);

हाँ, लेकिन यह है कि यदि वेबसाइट का उपयोग मेरे देश के भीतर किया जाता है, यदि इसका उपयोग किसी अन्य देश में किया जाता है जैसे कि संयुक्त राज्य अमेरिका - यह 2 नहीं होगा ...
चिह्न

जाहिर है, इस मूल्य की गणना की जानी चाहिए।
अनातोली

3
धन्यवाद ... मैं वास्तव में यहाँ एक महान पुस्तकालय पाया, blog.stevenlevithan.com/archives/date-time-format आप सभी को यह करने की आवश्यकता है (शायद यह आपकी मदद करेगा), आप झूठे पास करते हैं और यह परिवर्तित नहीं होता है। var कुछ = dateFormat (myStartDate, "isoDateTime", false);
निशान

11
यह गलत है क्योंकि यह आपके कोड को नॉन-टाइमज़ोन को सुरक्षित बनाता है - जब आप अपनी तारीख को वापस पढ़ते हैं तो आपको
टाइमज़ोन को

4
यह उत्तर गलत है। ओपी को यह एहसास नहीं है कि "2009-09-28T08: 00: 00Z" और "सोम सिपाही 28 10:00:00 UTC + 0200 2009" ठीक उसी समय के हैं और समय - सीमा के लिए समायोजन वास्तव में पैदा कर रहा है गलत समय।
रॉबजी

41

JSON Date.prototype.toISOStringफ़ंक्शन का उपयोग करता है जो स्थानीय समय का प्रतिनिधित्व नहीं करता है - यह अनमॉडिफाइड UTC में समय का प्रतिनिधित्व करता है - यदि आप अपनी तिथि आउटपुट को देखते हैं तो आप देख सकते हैं कि आप UTC + 2 घंटे में हैं, यही कारण है कि JSON स्ट्रिंग दो घंटे में बदलता है, लेकिन अगर यह एक ही समय को कई समय क्षेत्रों में सही ढंग से प्रतिनिधित्व करने की अनुमति देता है।


2
इस बारे में कभी नहीं सोचा, लेकिन आप सही हैं। यह समाधान है: मैं प्रोटोटाइपिंग का उपयोग करके अपने द्वारा पसंद किए जाने वाले किसी भी प्रारूप को निर्दिष्ट कर सकता हूं।
दौड़

16

केवल रिकॉर्ड के लिए, याद रखें कि अंतिम "Z" "2009-09-28T08: 00: 00Z" में इसका मतलब है कि समय वास्तव में UTC में है।

देखें http://en.wikipedia.org/wiki/ISO_8601 जानकारी के लिए।


9

यहाँ एक और जवाब है (और व्यक्तिगत रूप से मुझे लगता है कि यह अधिक उपयुक्त है)

var currentDate = new Date(); 
currentDate = JSON.stringify(currentDate);

// Now currentDate is in a different format... oh gosh what do we do...

currentDate = new Date(JSON.parse(currentDate));

// Now currentDate is back to its original form :)

@ रोहन इस बात की ओर इशारा करने के लिए शुक्रिया लेकिन सवाल पर टैग जावास्क्रिप्ट का उल्लेख करते हैं।
अगस्त

6

date.toJSON () UTC- दिनांक को एक स्ट्रिंग स्वरूपित में प्रिंट करता है (इसलिए इसे JSON प्रारूप में कनवर्ट करते समय इसके साथ ऑफसेट जोड़ता है)।

date = new Date();
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();

6
आमतौर पर यह एक अच्छा विचार है कि आपका कोड क्या करता है, इस पर एक स्पष्टीकरण जोड़ना है। यह नए डेवलपर्स को यह समझने की अनुमति देता है कि कोड कैसे काम करता है।
कालेब क्लेवेटर

क्या आप बता सकते हैं कि उत्तर में कोड क्यों काम करना चाहिए?
क्रिस्टिक

यह मेरे लिए भी काम करता है, लेकिन क्या आप बता सकते हैं कि आपने ऐसा कैसे किया?
देवेन पाटिल

मैं इस कोड की दूसरी पंक्ति को समझाने की कोशिश करूँगा .. date.getTime()मिलकॉन्ड्स में समय देता हूं , इसलिए हमें दूसरी ऑपरेंड को मिलीसेकंड में भी बदलना चाहिए। चूँकि date.getTimezoneOffset()मिनटों में ऑफसेट होता है, हम इसे 60000 से गुणा करते हैं, क्योंकि 1 मिनट = 60000milliseconds। इसलिए वर्तमान समय से ऑफसेट घटाकर हमें यूटीसी में समय मिलता है।
पावलोव

4

आप स्थानीय समय के साथ प्रारूप.जेएस का उपयोग कर सकते हैं :

Date.prototype.toISOString = function () {
    return moment(this).format("YYYY-MM-DDTHH:mm:ss");
};

सामान्य वर्ग दिनांक को अधिलेखित न करें। कुछ बाहरी मॉड्यूल का उपयोग करने पर यह आपके एप्लिकेशन को आसानी से तोड़ सकता है।
वायाचेस्लाव डोब्रोमाइसलोव

3

मुझे थोड़ी देर हो गई है, लेकिन आप इस तरह से प्रोटोटाइप का उपयोग करने की तिथि के मामले में हमेशा toJson फ़ंक्शन को अधिलेखित कर सकते हैं:

Date.prototype.toJSON = function(){
    return Util.getDateTimeString(this);
};

मेरे मामले में, Util.getDateTimeString (यह) इस तरह से एक स्ट्रिंग लौटाता है: "2017-01-19T00: 00, 00Z"


2
ध्यान दें कि ओवरब्रिज ब्राउज़र ग्लोबल्स आपके द्वारा एम्बेड किए गए तृतीय-पक्ष पुस्तकालयों को तोड़ सकते हैं, और एक बड़ा विरोधी पैटर्न है। उत्पादन में ऐसा कभी न करें।
jakub.g

2

आमतौर पर आप चाहते हैं कि तिथियां प्रत्येक उपयोगकर्ता को उसके स्थानीय समय में प्रस्तुत की जाएं-

यही कारण है कि हम GMT (UTC) का उपयोग करते हैं।

स्थानीय समय स्ट्रिंग प्राप्त करने के लिए Date.parse (jsondatestring) का उपयोग करें,

जब तक आप चाहते हैं आपके स्थानीय समय प्रत्येक आगंतुक को दिखाया।

उस स्थिति में, अनातोली की विधि का उपयोग करें।


2

moment.jsलाइब्रेरी (गैर-टाइमज़ोन संस्करण) का उपयोग करके इस मुद्दे के आसपास मिला ।

var newMinDate = moment(datePicker.selectedDates[0]);
var newMaxDate = moment(datePicker.selectedDates[1]);

// Define the data to ask the server for
var dataToGet = {"ArduinoDeviceIdentifier":"Temperatures",
                "StartDate":newMinDate.format('YYYY-MM-DD HH:mm'),
                "EndDate":newMaxDate.format('YYYY-MM-DD HH:mm')
};

alert(JSON.stringify(dataToGet));

मैं flatpickr.min.jsपुस्तकालय का उपयोग कर रहा था । परिणामी JSON ऑब्जेक्ट का समय स्थानीय समय प्रदान करता है लेकिन दिनांक पिकर है।


2

टाइम- JSON.stringifyज़ोन की अनदेखी करने के लिए आउट-ऑफ़-द-बॉक्स समाधान :

  • शुद्ध जावास्क्रिप्ट (अनातोली उत्तर पर आधारित):

// Before: JSON.stringify apply timezone offset
const date =  new Date();
let string = JSON.stringify(date);
console.log(string);

// After: JSON.stringify keeps date as-is!
Date.prototype.toJSON = function(){
    const hoursDiff = this.getHours() - this.getTimezoneOffset() / 60;
    this.setHours(hoursDiff);
    return this.toISOString();
};
string = JSON.stringify(date);
console.log(string);

पुस्तकालय का उपयोग कर क्षण:

const date =  new Date();
let string = JSON.stringify(date);
console.log(string);

Date.prototype.toJSON = function(){
    return moment(this).format("YYYY-MM-DDTHH:mm:ss:ms");;
};
string = JSON.stringify(date);
console.log(string);
<html>
  <header>
    <script src="https://momentjs.com/downloads/moment.min.js"></script>
    <script src="https://momentjs.com/downloads/moment-timezone-with-data-10-year-range.min.js"></script>
</header>
</html>


2

मैं इसे विरासत सामान के साथ काम कर रहा हूं, जहां वे केवल पूर्वी तट पर काम करते हैं और यूटीसी में तारीखों को स्टोर नहीं करते हैं, यह सभी ईएसटी है। मुझे ब्राउज़र में उपयोगकर्ता इनपुट के आधार पर तारीखों को फ़िल्टर करना है इसलिए JSON प्रारूप में स्थानीय समय में तारीख को पास करना होगा।

बस पहले से ही पोस्ट किए गए इस समाधान पर विस्तार से बताएं - यही वह है जो मैं उपयोग करता हूं:

// Could be picked by user in date picker - local JS date
date = new Date();

// Create new Date from milliseconds of user input date (date.getTime() returns milliseconds)
// Subtract milliseconds that will be offset by toJSON before calling it
new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toJSON();

इसलिए मेरी समझ यह है कि आगे बढ़ने और समय घटाया जाएगा (मिलीसेकंड में (इसलिए 60000)) टाइमजोन ऑफसेट (रिटर्न मिनट) के आधार पर प्रारंभिक तिथि से - toJSON () जोड़ने के लिए समय की प्रत्याशा में।


1

यहाँ कुछ सच में स्वच्छ और सरल (कम से कम मैं तो मानना है :)) और क्लोन या toJSON की तरह ब्राउज़र की मूल कार्यों के किसी भी अधिक भार होने के लिए तारीख का कोई जोड़-तोड़ की आवश्यकता है (संदर्भ: JSON करने के लिए एक जावास्क्रिप्ट दिनांक stringify और समय क्षेत्र की रक्षा कैसे , Shawson courtsy)

JSON.string को अपने दिल की सामग्री के लिए सामान प्रदान करता है कि एक प्रतिकृति समारोह पास !!! इस तरह से आपको घंटे और मिनट में अंतर या अन्य कोई हेरफेर नहीं करना है।

मैंने मध्यवर्ती परिणामों को देखने के लिए कंसोल में रखा है। इसलिए यह स्पष्ट है कि क्या चल रहा है और पुनरावृत्ति कैसे काम कर रही है। यह सूचना के योग्य कुछ का पता चलता है: मान को दोहराने के लिए मान पहले से ही आईएसओ तिथि प्रारूप में परिवर्तित हो गया है :)। मूल डेटा के साथ काम करने के लिए इस [कुंजी] का उपयोग करें।

var replacer = function(key, value)
{
    var returnVal = value;
    if(this[key] instanceof Date)
    {
        console.log("replacer called with key - ", key, " value - ", value, this[key]); 

        returnVal = this[key].toString();

        /* Above line does not strictly speaking clone the date as in the cloned object 
         * it is a string in same format as the original but not a Date object. I tried 
         * multiple things but was unable to cause a Date object being created in the 
         * clone. 
         * Please Heeeeelp someone here!

        returnVal = new Date(JSON.parse(JSON.stringify(this[key])));   //OR
        returnVal = new Date(this[key]);   //OR
        returnVal = this[key];   //careful, returning original obj so may have potential side effect

*/
    }
    console.log("returning value: ", returnVal);

    /* if undefined is returned, the key is not at all added to the new object(i.e. clone), 
     * so return null. null !== undefined but both are falsy and can be used as such*/
    return this[key] === undefined ? null : returnVal;
};

ab = {prop1: "p1", prop2: [1, "str2", {p1: "p1inner", p2: undefined, p3: null, p4date: new Date()}]};
var abstr = JSON.stringify(ab, replacer);
var abcloned = JSON.parse(abstr);
console.log("ab is: ", ab);
console.log("abcloned is: ", abcloned);

/* abcloned is:
 * {
  "prop1": "p1",
  "prop2": [
    1,
    "str2",
    {
      "p1": "p1inner",
      "p2": null,
      "p3": null,
      "p4date": "Tue Jun 11 2019 18:47:50 GMT+0530 (India Standard Time)"
    }
  ]
}
Note p4date is string not Date object but format and timezone are completely preserved.
*/

1

जावास्क्रिप्ट आमतौर पर स्थानीय समय क्षेत्र को यूटीसी में परिवर्तित करती है।

date = new Date();
date.setMinutes(date.getMinutes()-date.getTimezoneOffset())
JSON.stringify(date)

0

यदि आपके सर्वर बैकएंड समय-अज्ञेयवादी है या नहीं, तो सभी को उबला हुआ है। यदि यह नहीं है, तो आपको यह मानने की आवश्यकता है कि सर्वर का टाइमज़ोन क्लाइंट के समान है, या क्लाइंट के टाइमज़ोन के बारे में जानकारी स्थानांतरित करें और उसे भी गणना में शामिल करें।

एक PostgreSQL बैकेंड आधारित उदाहरण:

select '2009-09-28T08:00:00Z'::timestamp -> '2009-09-28 08:00:00' (wrong for 10am)
select '2009-09-28T08:00:00Z'::timestamptz -> '2009-09-28 10:00:00+02'
select '2009-09-28T08:00:00Z'::timestamptz::timestamp -> '2009-09-28 10:00:00'

अंतिम एक शायद वही है जो आप डेटाबेस में उपयोग करना चाहते हैं, यदि आप समयक्षेत्र तर्क को ठीक से लागू करने के इच्छुक नहीं हैं।


0

इसके बजाय toJSON, आप प्रारूप फ़ंक्शन का उपयोग कर सकते हैं जो हमेशा सही तिथि और समय देता है +GMT

यह सबसे मजबूत प्रदर्शन विकल्प है। यह टोकन की एक स्ट्रिंग लेता है और उन्हें अपने संबंधित मूल्यों के साथ बदल देता है।


0

मैंने इसे कोणीय 8 में आज़माया:

  1. मॉडल बनाएं:

    export class Model { YourDate: string | Date; }
  2. आपके घटक में

    model : Model;
    model.YourDate = new Date();
  3. बचत के लिए अपने एपीआई को तारीख भेजें

  4. एपीआई से अपना डेटा लोड करते समय आप इसे बनाएंगे:

    model.YourDate = new Date(model.YourDate+"Z");

आप अपने समय क्षेत्र के साथ अपनी तिथि सही ढंग से प्राप्त करेंगे।

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