2017-06-23 4 views
1

Je souhaite créer une classe Java avec des méthodes statiques thread-safe pour analyser les dates. Je comprends que certaines classes de date Java 7 (et antérieures) ne sont pas thread-safe. Quelle est la meilleure mise en œuvre de thread-safe en Java 8 de cette fonctionnalité:Java 8 meilleur moyen d'analyser la date du texte en timestamp milliseconde

String text = "5/16/2008"; 
long timestamp = DateUtil.getTimestamp(text); 

En Java 7 et plus tôt, vous feriez ceci:

public class DateUtil { 

    public static long getTimestamp(String text) { 
     DateFormat df = new SimpleDateFormat("M/d/yyyy"); 
     df.setTimeZone(TimeZone.getTimeZone("America/New_York")); 
     long timestamp = df.parse(text).getTime(); 
     return timestamp; 
    } 

} 

Mais au lieu de créer une nouvelle instance de DateFormat pour chaque appel, je veux partager une seule instance statique pour tous les appels à cette méthode getTimestamp statique. Ma compréhension est que ce n'est pas thread-safe.

Une exigence clé est que le texte que je veux analyser a une date courte comme "5/16/2008" sans la résolution HH: mm: ss.

Je ne veux pas non plus utiliser une bibliothèque tierce comme Joda-Time, mais plutôt des classes Java 8 standard.

+0

La bibliothèque Joda-Time tierce a été (principalement) transformée en classes Java 8 standard dans les paquets 'java.time. *'. –

Répondre

4

Voici une version de votre code refactored pour utiliser le package java.time.* dans Java 8. Il utilise une instance de formateur static final, qui est thread-safe et immuable, contrairement à java.text.SimpleDateFormat.

import java.time.LocalDate; 
import java.time.ZoneId; 
import java.time.format.DateTimeFormatter; 
import java.util.Date; 

public class DateUtil { 
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); 

    public static long getTimestamp(String text) { 
     LocalDate localDate = LocalDate.parse(text, formatter); 
     return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()).getTime(); 
    } 
} 
0

Vous pouvez utiliser joda-time lib. DateTime est immuable - et une fois créées, les valeurs ne changent pas, ainsi la classe peut être transmise en toute sécurité et utilisée dans plusieurs threads sans synchronisation.
Une classe modifiable compagnon de DateTime est MutableDateTime, dont la classe peut être modifiée et n'est pas adaptée aux threads.

DateTimeFormatter formatter = DateTimeFormat.forPattern("M/d/yyyy'T'HH:mm:ss.SSSZZ") 
    .withLocale(Locale.ROOT).withChronology(ISOChronology.getInstanceUTC()); 
DateTime dt = formatter.parseDateTime(text); 

Référence du DateTimeFormatt: DatetimeFormat api.

0

Comme indiqué dans la réponse de ck1, l'utilisation de java.time API est une meilleure approche que les classes héritées. DateTimeFormatter est immuable et thread-safe, et en utilisant une instance finale statique de celui-ci résoudra votre problème. La seule partie où je diffère de cette réponse est dans le code, où la classe Date est utilisée pour obtenir l'heure. Je voudrais également utiliser l'approche java.time ici. Voici ma version:

public class DateUtil { 

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy"); 

    public static long getTimestamp(String text) { 
     LocalDate localDate = LocalDate.parse(text, formatter); 
     return Instant.from(localDate.atStartOfDay(ZoneId.systemDefault())).toEpochMilli(); 
    } 

    public static void main(String[] args) { 
     String text = "5/16/2008"; 
     long timestamp = DateUtil.getTimestamp(text); 
     System.out.println(timestamp); 
    } 
}