8
votes

DateTime en UTC ne convertissant pas en Local

Je reçois une réponse DateTime de l'API qui définit le fuseau horaire sur UTC.

Mais quand j'essaye de convertir les données reçues en utilisant toLocal() cela ne convertit pas.

mon heure locale est HKT

voici mon code.

    //TIME DIFFERENCE
  getNotificationDate(DateTime date) {
    date = date.toUtc();
    final convertedDate = date.toLocal();

    final dateNow = DateTime.now();
    print('TIMENOW: ' + dateNow.toString());
    print('TIMENOTIFC: ' + convertedDate.toString());
    final difference = dateNow.difference(convertedDate);
    print('DIFFERENCE: ' + difference.toString());
    return getDurationFormat(difference);
  }

ÉDITER:

date est le DateTime que je reçois de l'API. qui est dans le fuseau horaire UTC.

J'ai utilisé print('TIMEZONENAME: ' + date.timeZoneName; et il définit automatiquement le fuseau horaire sur HKT . C'est pourquoi il ne fait rien lorsque j'essaie d'utiliser date.toLocal()


7 commentaires

Que voulez-vous dire par «ne pas convertir»? Le résultat n'est-il pas à l'heure locale (par exemple, selon isUtc )? Le moment n'est-il pas correct? Quel résultat attendiez- vous de votre programme d'exemple?


par exemple, mon heure local time actuelle est 23h00 . J'envoie maintenant 23h00 à l'API. Maintenant, mon 23h00 est converti par le backend en UTC qui deviendrait alors 15h08 car le DateTime du backend est défini sur UTC par défaut. Maintenant, je vais accéder à une page dans laquelle je reçois cette DateTime que je viens d'envoyer. Je pensais que par défaut, le flutter détecterait DateTime's fuseau horaire DateTime's mais je me trompais. flutter règle automatiquement la date / DateTime entrante sur mon fuseau horaire Local .


PS Je n'inclus pas mon local time comme paramètre lors de l'appel d'une requête POST . il serait simplement created_at sur le côté backends.


Dart DateTime ne prend en charge que deux fuseaux horaires - UTC et «local». Si vous obtenez une heure entrante et que vous créez un objet DateTime pour celle-ci, elle sera dans l'un de ces deux fuseaux horaires. Le "temps" entrant est probablement une chaîne, donc je suppose que vous l'analysez. Si cette chaîne contient, par exemple, un marqueur de fuseau horaire +02:00 elle est analysée comme UTC en soustrayant le décalage de fuseau horaire de la date analysée. S'il n'a pas de marqueur de fuseau horaire (pas de "+02" et pas de "Z"), il est interprété comme une heure locale.


malheureusement, il n'a pas +02 ou Z y aura-t-il un moyen de changer cela après l'avoir reçu?


Si vous obtenez la chaîne, vous pouvez y ajouter quelque chose, comme "Z", mais cela la fera être interprétée comme une heure UTC, pas comme l'heure locale de l'expéditeur. Si vous obtenez l'objet DateTime , vous devrez probablement créer un nouvel objet à partir de celui-ci, par exemple en faisant toString, en ajoutant "Z" et en l'analysant à nouveau. Si vous connaissez le fuseau horaire du serveur, disons UTC + 3, vous pouvez ajouter +03:00 après la chaîne et obtenir l'heure UTC correspondant à ce moment dans le temps


Avez-vous enfin trouvé quelque chose qui fonctionne? J'ai le même problème


5 Réponses :


4
votes
// you have time in utc
var dateUtc = DateTime.now().toUtc();
print("dateUtc: $dateUtc"); // 2019-10-10 12:05:01

// convert it to local
var dateLocal = dateUtc.toLocal();
print("local: $dateLocal"); // 2019-10-10 14:05:01
Can you see the difference in hours, in utc it is 12 and locally it is 14. 

7 commentaires

ce code renvoie les mêmes dates et heures. Comment puis-je vérifier mes paramètres régionaux?


@GiacomoM Le code ne renvoie pas les mêmes dates et heures, j'ai montré la sortie au format d'impression, vous pouvez voir qu'il y a un décalage horaire de GMT +2 (mon fuseau horaire local).


Je veux dire, j'ai essayé dans mon projet et j'obtiens la même heure: (je ne sais pas pourquoi


@GiacomoM Quel est votre fuseau horaire?


C'est l'Europe / Rome


@GiacomoM J'ai aussi le fuseau horaire +2. Je ne sais pas pourquoi le code n'a pas fonctionné.


Je reçois ceci: dateUtc: 2020-08-10 13:44:25.982856Z , local: 2020-08-10 13:44:25.982856 . Comme vous pouvez le voir, le Z a disparu, mais les heures sont les mêmes



2
votes

Vous pouvez essayer ce code:

getNotificationDate(DateTime date) {
    date = DateTime.utc(date.year,date.month,date.day,date.hour,date.minute,date.second);;
    final convertedDate = date.toLocal();

    final dateNow = DateTime.now();
    print('TIMENOW: ' + dateNow.toString());
    print('TIMENOTIFC: ' + convertedDate.toString());
    final difference = dateNow.difference(convertedDate);
    print('DIFFERENCE: ' + difference.toString());
    return getDurationFormat(difference);
  }


1 commentaires

time était déjà en local, alors quel est l'avantage de le changer en utc , puis de revenir au local ?



18
votes

Flutter nous a donné le moyen le plus simple de le convertir. Il vous suffit de passer utc: true lors de l'analyse de votre date.

var dateTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(dateUtc, true);
var dateLocal = dateTime.toLocal();

Entrée :

Supposons mon fuseau horaire: +05: 30

Date UTC -> 2020-02-12 23: 57: 02.000

Sortie :

Date locale -> 2020-02-12 18: 27: 02.019660


4 commentaires

Salut, cela ne fonctionne pas lorsque je passe une date comme celle-ci - 2020-08-15T05: 01: 31Z, qui est une date UTC valide.


@Varundroid Avez-vous essayé l'analyse avec "aaaa-MM-jjTHH: mm: ssZ"?


@Varundroid comme, var dateTime = DateFormat ("aaaa-MM-jjTHH: mm: ssZ"). Parse ("2020-08-15T05: 01: 3‌ 1Z", true);


Cela fonctionne bien mais DateFormat provient du package intl



0
votes

Installer le package intl depuis pub.dev

ajouter la ligne suivante:

//just make sure you have passed the right date format of utc("yyyy-MM-dd HH:mm:ss"). I have passed by default my format.

//for example
// 2020-11-25 24:12:36 -> "yyyy-MM-dd HH:mm:ss"
DateTime localDate=utcDateTime.toLocalDateTime();


//for different formats you can pass your own dateFormat for utcDate like below:
// 20-11-25 24:12:36 -> "yy-MM-dd HH:mm:ss"
DateTime localDate=utcDateTime.toLocalDateTime("yy-MM-dd HH:mm:ss");

extension DateTimeExtension on DateTime {
  DateTime toLocalDateTime({String format = "yyyy-MM-dd HH:mm:ss"}) {
    var dateTime = DateFormat(format).parse(this.toString(), true);
    return dateTime.toLocal();
  }
}

Vous pouvez créer une extension comme ci-dessous afin qu'elle soit très utile et facile à utiliser n'importe où dans un projet entier.

import 'package:intl/intl.dart';


0 commentaires

0
votes

Pour ceux qui analysent TimeStamp de Firestore.

* sentAt is Timestamp

String timeToDate = widget.sentAt.toDate().toString();
    var dateTime = DateFormat("yyyy-MM-dd HH:mm:ss").parse(timeToDate, true);
    var dateLocal = dateTime.toLocal();


0 commentaires