J'ai une colonne de date dans Excel, mais lorsque je lis dans mon application Java, je reçois une valeur en tant que nombre
Exemple
Date Excel
1/1/2013
Suis comme
41275.00
Comment convertir un nombre à ce jour dans mon application Java?
Voici un exemple de travail minimal expliquant comment convertir une date Excel en une date Java:
Date javaDate= DateUtil.getJavaDate((double) 41275.00);
System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(javaDate));
qui retourne
01/01/2013
Vous devez également importer les packages suivants:
Java.text.SimpleDateFormat
Java.util.Date
Apache POI a quelques utilitaires pour cela http://poi.Apache.org/apidocs/org/Apache/poi/ss/usermodel/DateUtil.html , notamment http://poi.Apache.org/ apidocs/org/Apache/poi/ss/usermodel/DateUtil.html # getJavaDate (double)
Remarque Excel stocke les dates sous forme de nombre de jours (plus des fractions de jours) depuis 1900 (et dans certains cas, il peut s'agir de 1904). Voir http://support.Microsoft.com/kb/180162 .
Utilisez les classes modernes Java.time.
LocalDate // Represent a date-only vaule, without time-of-day and without time zone.
.of( 1899 , Month.DECEMBER , 30 ) // Specify Epoch reference date used by *some* versions of Excel. Beware: Some versions use a 1904 Epoch reference. Returns a `LocalDate` object.
.plusDays( // Add a number of days.
(long) Double.parseDouble( "41275.00" ) // Get a number of whole days from your input string.
) // Returns another instance of a `LocalDate`, per Immutable Objects pattern, rather than altering the original.
.toString() // Generate text representing the value of this `LocalDate` in standard ISO 8601 format.
2013-01-01
La solution moderne utilise les classes Java.time qui ont supplanté les terribles anciennes classes date-heure associées aux versions les plus anciennes de Java.
Selon cette documentation , cette valeur de Microsoft Excel est le nombre de jours écoulés depuis la référence de l'époque du 1900-01-01 à UTC . En interne, la date de référence est le 30 décembre 1899, comme indiqué sur cette page Wikipedia .
Attention, certaines versions (anciennes versions pour macOS?) D'Excel utilisent une époque différente en 1904 .
Établissez la référence Epoch quelque part dans votre code.
final static public LocalDate Excel_Epoch_REFERENCE =
LocalDate.of( 1899 , Month.DECEMBER , 30 )
; // Beware: Some versions of Excel use a 1904 Epoch reference.
Analysez votre chaîne d’entrée comme une variable BigDecimal
pour la précision (par opposition aux types à virgule flottante qui échangent précision pour une exécution plus rapide).
BigDecimal countFromEpoch = new BigDecimal( "41275.00" );
Ajoutez le nombre de jours entiers à la date de référence Epoque.
long days = countFromEpoch.longValue(); // Extract the number of whole days, dropping the fraction.
LocalDate localDate = Excel_Epoch_REFERENCE.plusDays( days );
localDate.toString (): 2013-01-01
Le framework {JAVA.TIME} est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciennes classes legacy date-heure, telles que Java.util.Date
, Calendar
, & SimpleDateFormat
.
Le projet Joda-Time _ , désormais en mode de maintenance , conseille la migration vers les classes Java.time .
Pour en savoir plus, consultez le tutoriel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger des objets Java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou ultérieur. Pas besoin de chaînes, pas besoin de Java.sql.*
classes.
Où obtenir les classes Java.time?
Le projet ThreeTen-Extra étend Java.time avec des classes supplémentaires. Ce projet est un terrain d’essai pour d’éventuels ajouts à Java.time. Vous pouvez trouver ici quelques classes utiles telles que Interval
, YearWeek
, YearQuarter
, et more .
Les dates sérialisées d’Excel correspondent au nombre de jours écoulés depuis le 1/1/1900. Afin de retrouver la date, nous devons ajouter le numéro de série en jours.
pour Java 8 sans aucune dépendance
`` `
/*
1900-1-0 0
1900-1-1 1
1900-1-2 2
1900-1-3 3
*/
int days = 43323;
LocalDate start = LocalDate.of(1900, 1, 1);
LocalDate today = LocalDate.of(2018, 8, 11);
// days to date
LocalDate date = start.plusDays(days).minusDays(2);
System.out.println(date);
// date to days
long days1 = ChronoUnit.DAYS.between(start, today) + 2;
System.out.println(days1);
`` `