Een JavaScript-datum initialiseren naar een bepaalde tijdzone

Ik heb datum en tijd in een bepaalde tijdzone als een string en ik wil dit omzetten naar de lokale tijd. Maar ik weet niet hoe ik de tijdzone in het Date-object moet instellen.

Ik heb bijvoorbeeld Feb 28 2013 7:00 PM ET,dan kan ik

var mydate = new Date();
mydate.setFullYear(2013);
mydate.setMonth(02);
mydate.setDate(28);
mydate.setHours(7);
mydate.setMinutes(00);  

Voor zover ik weet, kan ik de UTC-tijd of de lokale tijd instellen. Maar hoe stel ik de tijd in in een andere tijdzone?

Ik heb geprobeerd de verschuiving van UTC op te tellen/af te trekken, maar ik weet niet hoe ik zomertijd kan tegengaan. Ik weet niet zeker of ik de goede kant op ga.

Hoe kan ik de tijd omzetten van een andere tijdzone naar lokale tijd in javascript?


Antwoord 1, autoriteit 100%

Achtergrond

JavaScript’s Date-object houdt intern de tijd in UTC bij, maar accepteert doorgaans invoer en produceert uitvoer in de lokale tijd van de computer waarop het draait. Het heeft zeer weinig faciliteiten om met tijd in andere tijdzones te werken.

De interne representatie van een Dateobject is een enkel getal, dat staat voor het aantal milliseconden dat is verstreken sinds 1970-01-01 00:00:00 UTC, zonder rekening te houden met schrikkelseconden. Er is geen tijdzone of tekenreeksindeling opgeslagen in het object Date zelf.Wanneer verschillende functies van het object Dateworden gebruikt, wordt de lokale tijdzone van de computer toegepast op de interne weergave . Als de functie een tekenreeks produceert, kan de landinstellingsinformatie van de computer in overweging worden genomen om te bepalen hoe die tekenreeks moet worden geproduceerd. De details verschillen per functie en sommige zijn implementatiespecifiek.

De enige bewerkingen die het object Datekan uitvoeren met niet-lokale tijdzones zijn:

  • Het kan een tekenreeks met een numerieke UTC-offset uit elke tijdzone ontleden. Het gebruikt dit om de waarde die wordt geparseerd aan te passen en slaat het UTC-equivalent op. De oorspronkelijke lokale tijd en offset worden niet behouden in het resulterende object Date. Bijvoorbeeld:

    var d = new Date("2020-04-13T00:00:00.000+08:00");
    d.toISOString()  //=> "2020-04-12T16:00:00.000Z"
    d.valueOf()      //=> 1586707200000  (this is what is actually stored in the object)
    
  • In omgevingen die de ECMASCript Internationalization API(ook bekend als ” Intl”), kan een Date-object een landspecifieke tekenreeks produceren die is aangepast aan een gegeven tijdzone-ID. Dit wordt bereikt via de optie timeZonenaar toLocaleStringen zijn variaties. De meeste implementaties ondersteunen IANA-tijdzone-ID’s, zoals 'America/New_York'. Bijvoorbeeld:

    var d = new Date("2020-04-13T00:00:00.000+08:00");
    d.toLocaleString('en-US', { timeZone: 'America/New_York' })
    //=> "4/12/2020, 12:00:00 PM"
    // (midnight in China on Apring 13th is noon in New York on April 12th)
    

    De meeste moderne omgevingen ondersteunen de volledige set IANA-tijdzone-ID’s (zie de compatibiliteitstabel hier). Houd er echter rekening mee dat de enige id die vereistwordt ondersteund door Intl, 'UTC'is, dus u moet zorgvuldig controleren of u oudere browsers of atypische omgevingen moet ondersteunen ( bijvoorbeeld lichtgewicht IoT-apparaten).

Bibliotheken

Er zijn verschillende bibliotheken die kunnen worden gebruikt om met tijdzones te werken. Hoewel ze het Date-object nog steeds niet anders kunnen laten gedragen, implementeren ze meestal de standaard IANA-tijdzonedatabase en bieden ze functies voor gebruik in JavaScript. Moderne bibliotheken gebruiken de tijdzonegegevens die worden geleverd door de Intl API, maar oudere bibliotheken hebben doorgaans overhead, vooral als u in een webbrowser werkt, omdat de database een beetje groot kan worden. Sommige van deze bibliotheken stellen u ook in staat om selectief de dataset te verkleinen, ofwel door de tijdzones die worden ondersteund en/of door het datumbereik waarmee u kunt werken.

Hier zijn de bibliotheken om te overwegen:

Intl-gebaseerde bibliotheken

Nieuwe ontwikkeling moet kiezen uit een van deze implementaties, die voor hun tijdzonegegevens afhankelijk zijn van de Intl API:

Niet-internationale bibliotheken

Deze bibliotheken worden onderhouden, maar dragen de last van het verpakken van hun eigen tijdzonegegevens, die behoorlijk groot kunnen zijn.

* Terwijl het moment en moment-timezone eerder aanbevolen waren, geeft het moment team de voorkeur aan gebruikers die Luxon voor nieuwe ontwikkeling koos.

Beëindigde bibliotheken

Deze bibliotheken zijn officieel beëindigd en mogen niet langer worden gebruikt.

Toekomstige voorstellen

De TC39 Temporeel voorstel streeft naar een nieuwe reeks standaardobjecten voor het werken met data en tijden in de JavaScript-taal zelf. Dit omvat ondersteuning voor een tijdzone bewust voorwerp.


Antwoord 2, Autoriteit 25%

Zoals Matt Johnson zei

Als u uw gebruik kunt beperken tot moderne webbrowsers, kunt u nu de
Volgend zonder speciale bibliotheken:

new Date().toLocaleString("en-US", {timeZone: "America/New_York"})

Dit is geen uitgebreide oplossing, maar het werkt voor veel scenario’s
die alleen uitvoerconversie vereisen (van UTC of lokale tijd naar a
specifieke tijdzone, maar niet de andere richting).

Dus hoewel de browser de IANA-tijdzones niet kan lezen bij het maken van een datum, of methoden heeft om de tijdzones op een bestaand Date-object te wijzigen, lijkt er een hack omheen te zijn:

function changeTimezone(date, ianatz) {
  // suppose the date is 12:00 UTC
  var invdate = new Date(date.toLocaleString('en-US', {
    timeZone: ianatz
  }));
  // then invdate will be 07:00 in Toronto
  // and the diff is 5 hours
  var diff = date.getTime() - invdate.getTime();
  // so 12:00 in Toronto is 17:00 UTC
  return new Date(date.getTime() - diff); // needs to substract
}
// E.g.
var here = new Date();
var there = changeTimezone(here, "America/Toronto");
console.log(`Here: ${here.toString()}\nToronto: ${there.toString()}`);

Antwoord 3, autoriteit 7%

U kunt een tijdzone-offset opgeven op new Date(), bijvoorbeeld:

new Date('Feb 28 2013 19:00:00 EST')

of

new Date('Feb 28 2013 19:00:00 GMT-0500')

Sinds DateUTC-tijd opslaat (dwz getTimeretourneert in UTC), zal javascript de tijd omzetten in UTC, en wanneer u zaken als toStringjavascript converteert de UTC-tijd naar de lokale tijdzone van de browser en retourneert de tekenreeks in de lokale tijdzone, bijvoorbeeld als ik UTC+8gebruik:

> new Date('Feb 28 2013 19:00:00 GMT-0500').toString()
< "Fri Mar 01 2013 08:00:00 GMT+0800 (CST)"

U kunt ook de normale getHours/Minute/Second-methode gebruiken:

> new Date('Feb 28 2013 19:00:00 GMT-0500').getHours()
< 8

( Deze 8betekent dat nadat de tijd is omgezet in mijn lokale tijd – UTC+8, het aantal uren 8is. )


Antwoord 4, autoriteit 6%

Dit zou je probleem moeten oplossen. Voel je vrij om oplossingen aan te bieden. Deze methode houdt ook rekening met de zomertijd voor de opgegeven datum.

dateWithTimeZone = (timeZone, year, month, day, hour, minute, second) => {
  let date = new Date(Date.UTC(year, month, day, hour, minute, second));
  let utcDate = new Date(date.toLocaleString('en-US', { timeZone: "UTC" }));
  let tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
  let offset = utcDate.getTime() - tzDate.getTime();
  date.setTime( date.getTime() + offset );
  return date;
};

Hoe te gebruiken met tijdzone en lokale tijd:

dateWithTimeZone("America/Los_Angeles",2019,8,8,0,0,0)

Antwoord 5, autoriteit 2%

Ik vond de meest ondersteunde manier om dit te doen, zonder me zorgen te maken over een bibliotheek van derden, door getTimezoneOffsette gebruiken om de juiste tijdstempel te berekenen, of door de tijd bij te werken en vervolgens de normale methoden te gebruiken om de benodigde datum en tijd.

var mydate = new Date();
mydate.setFullYear(2013);
mydate.setMonth(02);
mydate.setDate(28);
mydate.setHours(7);
mydate.setMinutes(00);
// ET timezone offset in hours.
var timezone = -5;
// Timezone offset in minutes + the desired offset in minutes, converted to ms.
// This offset should be the same for ALL date calculations, so you should only need to calculate it once.
var offset = (mydate.getTimezoneOffset() + (timezone * 60)) * 60 * 1000;
// Use the timestamp and offset as necessary to calculate min/sec etc, i.e. for countdowns.
var timestamp = mydate.getTime() + offset,
    seconds = Math.floor(timestamp / 1000) % 60,
    minutes = Math.floor(timestamp / 1000 / 60) % 60,
    hours   = Math.floor(timestamp / 1000 / 60 / 60);
// Or update the timestamp to reflect the timezone offset.
mydate.setTime(mydate.getTime() + offset);
// Then Output dates and times using the normal methods.
var date = mydate.getDate(),
    hour = mydate.getHours();

BEWERKEN

Ik gebruikte eerder UTC-methoden bij het uitvoeren van de datumtransformaties, wat onjuist was. Door de offset aan de tijd toe te voegen, zal het gebruik van de lokale get-functies de gewenste resultaten opleveren.


Antwoord 6

Voor Ionic-gebruikers had ik hier een hekel aan omdat .toISOString()moet worden gebruikt met de html-sjabloon.

Dit zal de huidige datum pakken, maar kan natuurlijk worden toegevoegd aan eerdere antwoorden voor een geselecteerde datum.

Ik heb het opgelost door dit te gebruiken:

date = new Date();
public currentDate: any = new Date(this.date.getTime() - this.date.getTimezoneOffset()*60000).toISOString();

Antwoord 7

Ik liep in een vergelijkbaar probleem met eenheidstests (specifiek in JEST wanneer de eenheidstests lokaal worden uitgevoerd om de snapshots te maken en vervolgens wordt de CI-server uitgevoerd in (potentieel) een andere tijdzone die de snapshotvergelijking veroorzaakt om te mislukken). Ik bespotte onze Dateen een deel van de ondersteunende methoden zoals SO:

describe('...', () => {
  let originalDate;
  beforeEach(() => {
    originalDate = Date;
    Date = jest.fn(
      (d) => {
        let newD;
        if (d) {
          newD = (new originalDate(d));
        } else {
          newD = (new originalDate('2017-05-29T10:00:00z'));
        }
        newD.toLocaleString = () => {
          return (new originalDate(newD.valueOf())).toLocaleString("en-US", {timeZone: "America/New_York"});
        };
        newD.toLocaleDateString = () => {
          return (new originalDate(newD.valueOf())).toLocaleDateString("en-US", {timeZone: "America/New_York"});
        };
        newD.toLocaleTimeString = () => {
          return (new originalDate(newD.valueOf())).toLocaleTimeString("en-US", {timeZone: "America/New_York"});
        };
        return newD;
      }
    );
    Date.now = () => { return (Date()); };
  });
  afterEach(() => {
    Date = originalDate;
  });
});

Antwoord 8

Ik had hetzelfde probleem, maar we kunnen de tijdzone die we willen gebruiken
We gebruiken .toLocaleDateString()

bijvoorbeeld:

var day=new Date();
const options= {day:'numeric', month:'long', year:"numeric", timeZone:"Asia/Kolkata"};
const today=day.toLocaleDateString("en-IN", options);
console.log(today);

Antwoord 9

Probeer ctoc vanaf npm te gebruiken.
https://www.npmjs.com/package/ctoc_timezone

Het heeft een eenvoudige functionaliteit om tijdzones te wijzigen (de meeste tijdzones rond de 400) en alle aangepaste formaten die u wilt weergeven.


Antwoord 10

Voortbouwend op de bovenstaande antwoorden, gebruik ik deze native one-liner om de lange tijdzonereeks om te zetten in de drieletterreeks:

var longTz = 'America/Los_Angeles';
var shortTz = new Date().
    toLocaleString("en", {timeZoneName: "short", timeZone: longTz}).
    split(' ').
    pop();

Dit geeft PDT of PST, afhankelijk van de opgegeven datum. In mijn specifieke gebruiksgeval, dat we ontwikkelen op Salesforce (Aura/Lightning), zijn we in staat om de tijdzone van de gebruiker in het lange formaat van de backend te krijgen.


Antwoord 11

Probeer: date-from-timezone, het lost de verwachte datum op met behulp van native beschikbaar Intl.DateTimeFormat.

Ik heb die methode al een paar jaar in een van mijn projecten gebruikt, maar nu heb ik besloten om het als een klein OS-project te publiceren 🙂


Antwoord 12

Ik ken zijn 3 jaar te laat, maar misschien kan het iemand anders helpen omdat ik niets dergelijks heb gevonden, behalve voor de moment-timezone-bibliotheek, wat niet precies hetzelfde is als wat hij hier vraagt.

Ik heb iets vergelijkbaar met de Duitse tijdzone,
Dit is een klein complex vanwege de zomertijd en sprongjaren waar je 366 dagen hebt.

Het heeft misschien een beetje werk nodig met de functie “IsdaylightsavingTimeingermany” terwijl verschillende tijdzonen op verschillende tijden de zomertijd veranderen.

Hoe dan ook, bekijk deze pagina:
https://github.com/zerkotin/german-timezone-converter/wiki

De hoofdmethoden zijn:
ConvertLocaldatetogermantimeZone
ConvertedermandatoLocalTimeZone

Ik heb een poging gedaan om het te documenteren, dus het zal niet zo verwarrend zijn.


Antwoord 13

//For mumbai time diffrence is 5.5 hrs so
// city_time_diff=5.5 (change according to your city) 
let timee= Date.now()
    timee=timee+(3600000*city_time_diff); //Add our city time (in msec) 
    let new_date=new Date(timee)
console.log("My city time is: ",new_date);

Antwoord 14

werd geconfronteerd met hetzelfde probleem, gebruikte deze

console.log (datum.parse (“13 juni 2018 10:50:39 GMT + 1”));

Het zal milliseconden terugkeren waaraan u kunt controleren, heeft +100 Timzone Intialize Britse tijd
Ik hoop dat het helpt !!

Other episodes