Convertir la Date / L'heure pour un fuseau horaire donné-java

je veux convertir ce GMT Time stamp en GMT+13:

2011-10-06 03:35:05

j'ai essayé environ 100 combinaisons différentes de DateFormat, fuseau horaire, Date, GregorianCalendar etc. pour essayer de faire cette tâche très basique.

ce code fait ce que je veux pour l'heure actuelle:

Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

String newZealandTime = formatter.format(calendar.getTime());

mais ce que je veux c'est régler l'heure plutôt que d'utiliser l'heure actuelle.

j'ai trouvé que chaque fois que j'essaie de régler le moment comme celui-ci:

calendar.setTime(new Date(1317816735000L));

le fuseau horaire de la machine locale est utilisé. Pourquoi est-ce? Je sais que lorsque "new Date ()" retourne UTC+0 time alors pourquoi lorsque vous définissez L'heure en millisecondes ne suppose-t-il plus que L'heure est en UTC?

est possible de:

  1. fixe l'heure sur un objet (Calendrier/Date/horodatage)
  2. (peut-être) définit le fuseau horaire de l'horodatage initial (calendrier.setTimeZone(...))
  3. formater L'horodatage avec un nouveau fuseau horaire (formatter.setTimeZone(...)))
  4. renvoie une chaîne avec un nouveau fuseau horaire. (formateur.(format de calendrier.getTime ()))

merci à l'avance pour toute aide: d

54
demandé sur travega 2011-10-06 08:38:54

14 réponses

il est très important de comprendre comment fonctionne le temps passé à l'ordinateur. Cela dit, je suis d'accord que si une API est créée pour vous aider à traiter le temps informatique comme du temps réel, elle devrait fonctionner de manière à ce que vous puissiez la traiter comme du temps réel. La plupart du temps, c'est le cas, mais il y a des oublis majeurs qui nécessitent une attention.

de toute façon je digresse!! Si vous avez votre UTC offset (mieux pour travailler en UTC que les offsets GMT), vous pouvez calculer le temps en millisecondes et ajoute ça à ton horodatage. Notez qu'un Timestamp SQL peut varier d'un timestamp Java car la façon dont le passage de l'époque est calculée n'est pas toujours la même - dépendant des technologies de base de données et aussi des systèmes d'exploitation.

je vous conseille d'utiliser le Système.currentTimeMillis () comme vos horodateurs comme ceux-ci peuvent être traités de manière plus cohérente en java sans se soucier de convertir les horodateurs SQL en objets java Date, etc.

à Calculez votre offset vous pouvez essayer quelque chose comme ceci:

Long gmtTime =1317951113613L; // 2.32pm NZDT
Long timezoneAlteredTime = 0L;

if (offset != 0L) {
    int multiplier = (offset*60)*(60*1000);
    timezoneAlteredTime = gmtTime + multiplier;
} else {
    timezoneAlteredTime = gmtTime;
}

Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(timezoneAlteredTime);

DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");

formatter.setCalendar(calendar);
formatter.setTimeZone(TimeZone.getTimeZone(timeZone));

String newZealandTime = formatter.format(calendar.getTime());

j'espère que c'est utile!

27
répondu Mukul Goel 2014-09-25 15:53:16

pour moi, la façon la plus simple de le faire est:

Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
//Will print in UTC
System.out.println(sdf.format(calendar.getTime()));    

//Here you set to your timezone
sdf.setTimeZone(TimeZone.getDefault());
//Will print on your default Timezone
System.out.println(sdf.format(calendar.getTime()));
34
répondu Charleston 2016-10-07 19:11:59

comme toujours, je recommande la lecture de cet article sur la date et l'heure en Java afin que vous le compreniez.

l'idée de base est que 'sous le capot' tout est fait en UTC millisecondes depuis l'époque. Cela signifie qu'il est plus facile si vous opérez sans utiliser de fuseaux horaires du tout, à l'exception du formatage de chaîne pour l'utilisateur.

par conséquent, je sauterais la plupart des étapes que vous avez suggérées.

  1. fixe l'heure sur un objet (Date, Calendrier, etc.).
  2. définit le fuseau horaire sur un objet formatter.
  3. renvoie une chaîne de caractères du formatteur.

alternativement, vous pouvez utiliser Joda time . J'ai entendu dire que c'est une API datetime beaucoup plus intuitive.

20
répondu Bringer128 2011-10-06 05:03:56

tl; dr

si elle est saisie de 1317816735000L ...

Instant.ofEpochMilli( 1_317_816_735_000L )     // Represent a moment in UTC using a count of milliseconds since the epoch reference of 1970-01-01T00:00Z.
.atZone( ZoneId.of( "Pacific/Auckland" ) )     // Adjust from UTC into the wall-clock time used by the people of a certain region (a time zone). Returns a `ZonedDateTime` object.
.format(                 
    DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM )
    .withLocale( new Locale( "en" , "NZ" ) )   // Locale specifies the human language and cultural norms used in localization.
)                                              // Returns a `String` object that represents the value of our `ZonedDateTime` object’s value.

si elle est saisie de 2011-10-06 03:35:05 ...

LocalDateTime.parse(                  // Parse input string lacking any indicator of time zone or offset-from-UTC using the `LocalDateTime` class.
    "2011-10-06 03:35:05"
    .replace( " " , "T" )             // Comply with ISO 8601 standard by replacing SPACE in the middle with a `T`.
)                                     // Returns a `LocalDateTime` object.
.atZone(                              // Adjust from UTC into the wall-clock time used by the people of a certain region (a time zone). Returns a `ZonedDateTime` object.
    ZoneId.of( "Pacific/Auckland" )   // Always specify a time zone by `Continent/Region` name. Never use 3-4 pseudo-time-zones such as `PST`, `CST`, or `IST`.
)                                     // Returns a `ZonedDateTime` object.

de java.temps

la Question et la plupart des réponses utilisent des classes de date-heure périmées des premières versions de Java. Ces anciennes classes se sont révélées être gênantes et déroutantes. Les éviter. Utilisez plutôt le java.les classes de temps.

ISO 8601

votre chaîne de caractères est presque dans le format standard ISO 8601 . Il suffit de remplacer l'espace au milieu par un T .

String input = "2011-10-06 03:35:05".replace( " " , "T" ) ;  // Comply with ISO 8601 standard format by replacing the SPACE with a `T`.

Le de java.les classes de temps utilisent ces formats standards par défaut lors de l'analyse/génération de chaînes. Donc pas besoin de spécifier le format.

LocalDateTime

Maintenant analyser comme un LocalDateTime parce que l'entrée ne contient aucune information sur la compensation-par-UTC ou le fuseau horaire. Un LocalDateTime n'a pas de concept d'offset ni de fuseau horaire, donc il ne pas représentent un moment réel sur la ligne de temps.

LocalDateTime ldt = LocalDateTime.parse( input );

ZoneOffset

vous semblez dire que dans le contexte commercial vous savez que l'intention de cette chaîne est de représenter un moment qui est de 13 heures d'avance sur UTC. Nous avons donc instancier un ZoneOffset .

ZoneOffset offset = ZoneOffset.ofHours( 13 ); // 13 hours ahead of UTC, in the far east of the globe.

OffsetDateTime

appliquez-le pour obtenir un objet OffsetDateTime . Ceci devient un moment réel sur la ligne du temps.

OffsetDateTime odt = ldt.atOffset( offset);

ZoneId

mais vous mentionnez la Nouvelle-Zélande. Vous aviez donc un fuseau horaire précis en tête. Un fuseau horaire est un décalage de-UTC plus un ensemble des règles pour traiter les anomalies telles que L'heure D'été (HNT). Nous pouvons donc spécifier un ZoneId à un ZonedDateTime plutôt qu'un simple offset.

spécifier un nom du fuseau horaire approprié . N'utilisez jamais l'abréviation de 3 ou 4 lettres comme EST ou IST car elles ne sont pas de véritables fuseaux horaires, ni normalisées, ni même uniques(!). Par exemple, Pacific/Auckland .

ZoneId z = ZoneId.of( "Pacific/Auckland" );

ZonedDateTime

appliquer le ZoneId .

ZonedDateTime zdt = ldt.atZone( z );

vous pouvez facilement vous ajuster dans une autre zone pour le même moment sur la ligne de temps.

ZoneId zParis = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdtParis = zdt.withZoneSameInstant( zParis );  // Same moment in time, but seen through lens of Paris wall-clock time.

le Comte d'époque

je recommande fortement de ne pas manipuler les valeurs de date-heure comme un compte d'époque, comme millisecondes à partir du début de 1970 UTC. Mais si vous devez, créer un Instant à partir d'un tel nombre.

Instant instant = Instant.ofEpochMilli( 1_317_816_735_000L );

puis assigner un fuseau horaire tel que vu ci-dessus, si désiré, pour s'éloigner de UTC.

ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = instant.atZone( z );

votre valeur de 1_317_816_735_000L est:

  • 2011-10-05T12:12:15Z (Wed, 05 Oct 2011 12:12: 15 GMT)
  • 2011-10-06T01:12:15+13:00[Pacific/Auckland] (jeudi 06 octobre 2011 01:12:15 à Auckland Nouvelle-Zélande).

Générer des chaînes

pour générer une chaîne dans la norme ISO 8601 format, il suffit d'appeler toString . Notez que ZonedDateTime étend sagement le format standard en ajoutant le nom du fuseau horaire entre crochets.

String output = zdt.toString();

pour les autres formats, rechercher le débordement de la pile pour DateTimeFormatter classe. Déjà couvert plusieurs fois.

Spécifier FormatStyle et un Locale .

Locale l = new Locale( "en" , "NZ" );
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.MEDIUM ).withLocale( l );
String output = zdt.format( f );

à Propos de de java.heure

Le de java.time framework est construit dans Java 8 et plus tard. Ces classes remplacent les anciennes classes de date legacy telles que java.util.Date , Calendar , & SimpleDateFormat .

le Joda-Time projet, maintenant en mode maintenance , conseille la migration vers le java.temps classes.

pour en savoir plus, voir le Oracle Tutorial . Et rechercher le débordement de la pile pour de nombreux exemples et explications. La spécification est JSR 310 .

You peut échanger java.temps objets directement avec votre base de données. Utiliser un JDBC driver conforme à JDBC 4.2 ou plus tard. Pas besoin de Chaînes, pas besoin de classes java.sql.* .

où obtenir le java.les classes de temps?

The ThreeTen-Extra le projet étend java.temps avec des cours supplémentaires. Ce projet est un terrain d'expérimentation pour d'éventuelles futures additions à java.temps. Vous pouvez trouver ici quelques cours utiles tels que: Interval , YearWeek , YearQuarter , et plus .

7
répondu Basil Bourque 2018-06-29 19:51:44

avait un regard sur et je ne pense pas qu'il y ait un fuseau horaire en Java qui soit GMT + 13. Donc je pense que vous devez utiliser:

Calendar calendar = Calendar.getInstance();
//OR Calendar.getInstance(TimeZone.getTimeZone("GMT"));

calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY)+13);

Date d = calendar.getTime();

(s'il y a alors changer" GMT "à ce fuseau horaire et supprimer la deuxième ligne de code)

ou

SimpleDateFormat df = new SimpleDateFormat();
df.setTimeZone(TimeZone.getTimeZone("GMT+13"));
System.out.println(df.format(c.getTime()));

Si vous souhaitez définir une date, vous pouvez également utiliser:

    calendar.set(Calendar.DATE, 15);
calendar.set(Calendar.MONTH, 3);
calendar.set(Calendar.YEAR, 2011);
calendar.set(Calendar.HOUR_OF_DAY, 13); 
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 00);
4
répondu Craig 2011-10-06 10:14:44

la solution est en fait assez simple (Java pur, simple):

System.out.println(" NZ Local Time: 2011-10-06 03:35:05");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime localNZ = LocalDateTime.parse("2011-10-06 03:35:05",formatter);
ZonedDateTime zonedNZ = ZonedDateTime.of(localNZ,ZoneId.of("+13:00"));
LocalDateTime localUTC = zonedNZ.withZoneSameInstant(ZoneId.of("UTC")).toLocalDateTime();
System.out.println("UTC Local Time: "+localUTC.format(formatter));

SORTIE:

 NZ Local Time: 2011-10-06 03:35:05
UTC Local Time: 2011-10-05 14:35:05
4
répondu J S Raggio 2015-03-09 16:09:58

Joda-Time

La java.util.Les classes de Date / Calendrier sont un gâchis et doivent être évitées.

mise à jour: le projet Joda-Time est en mode maintenance. L'équipe conseille la migration vers le java.les classes de temps.

Voici votre réponse en utilisant la bibliothèque Joda-Time 2.3. Très facile.

comme indiqué dans le code d'exemple, je vous suggère d'utiliser les fuseaux horaires nommés dans la mesure du possible afin que votre programmation puisse gérer heure D'été (HNR) et autres anomalies.

si vous aviez placé un T au milieu de votre chaîne au lieu d'un espace, vous pourriez sauter les deux premières lignes de code, traitant d'un formatteur pour analyser la chaîne. Le constructeur DateTime peut prendre une chaîne dans le format ISO 8601 .

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;

// Parse string as a date-time in UTC (no time zone offset).
DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern( "yyyy-MM-dd' 'HH:mm:ss" );
DateTime dateTimeInUTC = formatter.withZoneUTC().parseDateTime( "2011-10-06 03:35:05" );

// Adjust for 13 hour offset from UTC/GMT.
DateTimeZone offsetThirteen = DateTimeZone.forOffsetHours( 13 );
DateTime thirteenDateTime = dateTimeInUTC.toDateTime( offsetThirteen );

// Hard-coded offsets should be avoided. Better to use a desired time zone for handling Daylight Saving Time (DST) and other anomalies.
// Time Zone list… http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZoneTongatapu = DateTimeZone.forID( "Pacific/Tongatapu" );
DateTime tongatapuDateTime = dateTimeInUTC.toDateTime( timeZoneTongatapu );

Vidage de ces valeurs...

System.out.println( "dateTimeInUTC: " + dateTimeInUTC );
System.out.println( "thirteenDateTime: " + thirteenDateTime );
System.out.println( "tongatapuDateTime: " + tongatapuDateTime );

Lors de l'exécuter...

dateTimeInUTC: 2011-10-06T03:35:05.000Z
thirteenDateTime: 2011-10-06T16:35:05.000+13:00
tongatapuDateTime: 2011-10-06T16:35:05.000+13:00
2
répondu Basil Bourque 2016-09-02 20:46:29

j'ai essayé ce code

try{
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss Z");
            Date datetime = new Date();

            System.out.println("date "+sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

            System.out.println("GMT "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("GMT+13"));

            System.out.println("GMT+13 "+ sdf.format(datetime));

            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));

            System.out.println("utc "+sdf.format(datetime));

            Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));

            DateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss z");    
            formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));  

            String newZealandTime = formatter.format(calendar.getTime());

            System.out.println("using calendar "+newZealandTime);

        }catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

et obtenir ce résultat

date 06-10-2011 10:40:05 +0530
GMT 06-10-2011 05:10:05 +0000 // here getting 5:10:05
GMT+13 06-10-2011 06:10:05 +1300 // here getting 6:10:05
utc 06-10-2011 05:10:05 +0000
using calendar 06 Oct 2011 18:10:05 GMT+13:00
1
répondu Pratik 2011-10-06 05:13:40

nous pouvons gérer cela en utilisant la valeur offset

 public static long convertDateTimeZone(long lngDate, String fromTimeZone,
        String toTimeZone){
    TimeZone toTZ = TimeZone.getTimeZone(toTimeZone);
    Calendar toCal = Calendar.getInstance(toTZ);        

    TimeZone fromTZ = TimeZone.getTimeZone(fromTimeZone);
    Calendar fromCal = Calendar.getInstance(fromTZ);
    fromCal.setTimeInMillis(lngDate);
    toCal.setTimeInMillis(fromCal.getTimeInMillis()
            + toTZ.getOffset(fromCal.getTimeInMillis())
            - TimeZone.getDefault().getOffset(fromCal.getTimeInMillis()));      
    return toCal.getTimeInMillis();
}

code d'essai snippet:

 System.out.println(new Date().getTime())
 System.out.println(convertDateTimeZone(new Date().getTime(), TimeZone
                .getDefault().getID(), "EST"));

sortie: 1387353270742 1387335270742

1
répondu DeepaGanesh 2013-12-18 07:58:16

nous pouvons obtenir L'heure UTC/GMT de la date donnée.

/**
 * Get the time stamp in GMT/UTC by passing the valid time (dd-MM-yyyy HH:mm:ss)
 */
public static long getGMTTimeStampFromDate(String datetime) {
    long timeStamp = 0;
    Date localTime = new Date();

    String format = "dd-MM-yyyy HH:mm:ss";
    SimpleDateFormat sdfLocalFormat = new SimpleDateFormat(format);
    sdfLocalFormat.setTimeZone(TimeZone.getDefault());

    try {

        localTime = (Date) sdfLocalFormat.parse(datetime); 

        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
                Locale.getDefault());
        TimeZone tz = cal.getTimeZone();

        cal.setTime(localTime);

        timeStamp = (localTime.getTime()/1000);
        Log.d("GMT TimeStamp: ", " Date TimegmtTime: " + datetime
                + ", GMT TimeStamp : " + localTime.getTime());

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return timeStamp;

}

il retournera L'heure UTC basée sur la date passée.

  • nous pouvons faire marche arrière comme l'heure UTC à la date et à l'heure courante(vice versa)

        public static String getLocalTimeFromGMT(long gmtTimeStamp) {
                 try{
                        Calendar calendar = Calendar.getInstance();
                        TimeZone tz = TimeZone.getDefault();
                        calendar.setTimeInMillis(gmtTimeStamp * 1000);
        //              calendar.add(Calendar.MILLISECOND, tz.getOffset(calendar.getTimeInMillis())); 
                        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
                        Date currenTimeZone = (Date) calendar.getTime();
                        return sdf.format(currenTimeZone);
                    }catch (Exception e) {
                    }
                    return "";  
                }
    

j'espère que cela aidera d'autres. Merci!!

0
répondu jagdish 2014-12-05 14:46:04

un chemin rapide est:

String dateText ="Thu, 02 Jul 2015 21:51:46";
long hours = -5; // time difference between places

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(E, dd MMM yyyy HH:mm:ss, Locale.ENGLISH);     
LocalDateTime date = LocalDateTime.parse(dateText, formatter);        
date = date.with(date.plusHours(hours));

System.out.println("NEW DATE: "+date);

sortie

NOUVELLE DATE: 2015-07-02T16: 51: 46

0
répondu Ev. 2015-07-02 22:52:17
public Timestamp convertLocalTimeToServerDatetime(String dt,String timezone){

    String clientDnT = dt ;// "2017-06-01 07:20:00";
    try{
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = sdf.parse(clientDnT);
    TimeZone tz = TimeZone.getTimeZone(timezone.trim()); // get time zone of user
    sdf.setTimeZone(tz);

    // Convert to servertime zone 
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    TimeZone tzInAmerica = TimeZone.getDefault();
    sdf1.setTimeZone(tzInAmerica);

    // assign date to date
    String serverDate = sdf1.format(date);

    // Convert to servertime zone to Timestamp
    Date date2 =  sdf.parse(serverDate);
    Timestamp tsm = new Timestamp(date2.getTime());
    return  tsm;
    }
    catch(Exception e){
        System.err.println(e);
    }

    return null;
}
0
répondu Sourav Barman 2017-06-02 07:27:53

un moyen facile. Une chose importante à se rappeler que la Date ne maintient pas le fuseau horaire, son seul numéro long millis , comme il a traité ici.

/**
 * Converts source in GMT+0 to timezone specified by server
 * 
 * @throws IllegalStateException if server timezone wasnt set
 */
public static Date convertGmt(Date source)
{
    if (timeZoneServer == null)
    {
        throw new IllegalStateException("Server timezone wasnt set");
    }

    long rawOffset = timeZoneServer.getRawOffset();

    Date dest = new Date(source.getTime() + rawOffset);

    return dest;
}

/**
 * Converts source in device timezone format to GMT
 */
public static Date convertToGmt(Date source)
{
    int rawOffset = TimeZone.getDefault().getRawOffset();

    Date dest = new Date(source.getTime() - rawOffset);

    return dest;
}

TimezoneServer est quelque chose comme TimeZone timeZoneServer = TimeZone.getTimeZone("GMT+1")

-1
répondu Serge 2013-12-11 06:58:30

Votre approche fonctionne sans aucune modification.

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
// Timestamp for 2011-10-06 03:35:05 GMT
calendar.setTime(new Date(1317872105000L));

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); 
formatter.setTimeZone(TimeZone.getTimeZone("GMT+13"));

// Prints 2011-10-06 16:35:05 GMT+13:00
System.out.println(formatter.format(calendar.getTime()));
-1
répondu augurar 2016-04-16 09:35:37