2016-04-29 2 views
1

J'essaye de convertir de java.sql.timestamp à OffsetDateTime de sorte que je puisse retourner ISO8601 chaîne standard dans mon api de repos. J'utilise ce code pour convertir timestamp à OffsetDateTimeID invalide pour ZoneOffset

public static OffsetDateTime sqlTimetampeToOffsetDateTime(Timestamp ts, String timeZone) 
{ 
    if (ts == null) 
    { 
     return null; 
    } 

    Calendar cal = Calendar.getInstance(); 
    cal.setTime(ts); 
    ZoneOffset offset = ZoneOffset.of(timeZone); 
    return OffsetDateTime.of(
      cal.get(Calendar.YEAR), 
      cal.get(Calendar.MONTH)+1, 
      cal.get(Calendar.DAY_OF_MONTH), 
      cal.get(Calendar.HOUR_OF_DAY), 
      cal.get(Calendar.MINUTE), 
      cal.get(Calendar.SECOND), 
      cal.get(Calendar.MILLISECOND)*1000000, 
      offset); 
} 

Cependant, le code échoue à ZoneOffset offset = ZoneOffset.of(timezone) pour la valeur Europe/Copenhagen.

J'utilise le code suivant pour imprimer la liste de tous les fuseaux horaires et je ne vois Europe/Copenhagen dans cette liste

Set<String> allZones = ZoneId.getAvailableZoneIds(); 
    LocalDateTime dt = LocalDateTime.now(); 

    List<String> zoneList = new ArrayList<String>(allZones); 
    Collections.sort(zoneList); 

    for (String s : zoneList) { 
     ZoneId zone = ZoneId.of(s); 
     ZonedDateTime zdt = dt.atZone(zone); 
     ZoneOffset offset = zdt.getOffset(); 
     int secondsOfHour = offset.getTotalSeconds() % (60 * 60); 
     String out = String.format("%35s %10s%n", zone, offset); 
     System.out.printf(out); 
    } 

Maintenant, je ne comprends pas ce qui se passe. Comment puis-je convertir java.sql.timestamp-ISO8601 chaîne (je ne se soucient pas si je dois utiliser OffsetDateTime ou non. Je préférerais ne pas utiliser une bibliothèque tierce partie

http://pastebin.com/eHJKWpAv

+0

Quel est votre type de données dans votre base de données? horodatage avec fuseau horaire? Autre chose? – Tunaki

+0

Dans la base de données j'ai timestam par exemple, «2016-05-23 15: 00: 00.0» et j'ai une autre colonne qui a un fuseau horaire, par exemple, «Europe/Copenhague». C'est pourquoi je passe 'timezone' comme une chaîne séparée. –

+0

L'expression 'ZoneOffset.of (" Europe/Copenhagen ")' doit échouer car cet ID de zone n'est PAS un simple décalage (contient des informations supplémentaires telles que les règles d'économie d'énergie). Dans ce cas, vous devez d'abord construire un 'ZonedDateTime', puis en déduire un' OffsetDateTime' ou un 'Instant'. –

Répondre

-1

J'ai réussi à le convertir, mais je ne suis pas sûr si elle est la bonne façon de le faire ou non. Voici mon code pour quelqu'un d'autre qui est à la recherche de la réponse

public static OffsetDateTime sqlTimetampeToOffsetDateTime(Timestamp ts, String timeZone) 
{ 
    if (ts == null) 
    { 
     return null; 
    } 

    ZoneId zoneId = ZoneId.of(timeZone); 

    Calendar cal = Calendar.getInstance(); 
    cal.setTime(ts); 
    ZonedDateTime zdt = ZonedDateTime.of(
      cal.get(Calendar.YEAR), 
      cal.get(Calendar.MONTH) + 1, 
      cal.get(Calendar.DAY_OF_MONTH), 
      cal.get(Calendar.HOUR_OF_DAY), 
      cal.get(Calendar.MINUTE), 
      cal.get(Calendar.SECOND), 
      cal.get(Calendar.MILLISECOND) * 1000000, 
      zoneId); 
    return zdt.toOffsetDateTime(); 
} 

timeZone est sous forme de Europe/Copenhagen ... vous pouvez voir la liste complète qui est pris en charge par Java8 en m y pastebin url affichée dans la question

+0

Je pense 'retourner ts.toInstant(). AtZone (ZoneId.of (timeZone)). ToOffsetDateTime();' est tout ce qui est nécessaire. – Tunaki

+0

votre code ajoute un décalage à l'heure résultante. Je voulais juste l'écrire ici pour que si quelqu'un d'autre lit, il connaisse la différence. –

+0

Ok, alors il s'agit de 'ts.toLocalDateTime(). AtZone (ZoneId.of (fuseau horaire)). ToOffsetDateTime();'. – Tunaki

0

Si vous avez le IDZone, il est assez trivial d'utiliser la classe instantanée pour ce faire:

Timestamp t = new Timestamp(System.currentTimeMillis()); 

ZoneId zone = ZoneId.of("Europe/Copenhagen"); 

OffsetDateTime offsetDateTime = ZonedDateTime 
    .ofInstant(Instant.ofEpochMilli(t.getTime()), zone) 
    .toOffsetDateTime(); 
0

ZoneOffset n'a de sens que lorsqu'il s'agit d'un point précis dans le temps. En Europe/Londres, nous utilisons actuellement BST ou GMT en fonction de la période de l'année. Cependant, il y a 100 ans (donner ou prendre), Europe/Londres n'avait pas de BST. ZoneOffset.of() récupère uniquement les offsets de zone à partir d'un cache interne qui n'est rempli que lorsque ZoneOffset.ofTotalSeconds() est appelée. Ceci est mal documenté. Cependant, il existe une solution facile:

ZoneId.of("Europe/London").getRules().getOffset(Instant.now()); 

qui renvoie la ZoneOffset correcte pour l'Europe/Londres pour le moment (aujourd'hui, par exemple)