Calcolo delle date Java

Per tenere traccia del tempo, Java conta il numero di millisecondi dall'inizio del 1 gennaio 1970. Ciò significa, ad esempio, che il 2 gennaio 1970 è iniziato 86.400.000 millisecondi dopo. Allo stesso modo, il 31 dicembre 1969 ha avuto inizio con 86.400.000 millisecondi prima del 1 gennaio 1970. La Dateclasse Java tiene traccia di quei millisecondi come longvalore. Poiché longè un numero longcon segno , le date possono essere espresse prima e dopo l'inizio del 1 gennaio 1970. I più grandi valori positivi e negativi esprimibili dalla primitiva possono generare date avanti e indietro di circa 290.000.000 di anni, che si adattano agli orari della maggior parte delle persone.

La classe Date

La Dateclasse, che si trova nel java.utilpacchetto, incapsula un longvalore che rappresenta un momento specifico nel tempo. Un utile costruttore è Date(), che crea un Dateoggetto che rappresenta l'ora in cui l'oggetto è stato creato. Il getTime()metodo restituisce il longvalore di un Dateoggetto. Nel programma seguente, utilizzo il Date()costruttore per creare una data basata su quando è stato eseguito il programma e il getTime()metodo per scoprire il numero di millisecondi che la data rappresenta:

import java.util. *; public class Now {public static void main (String [] args) {Date now = new Date (); long nowLong = now.getTime (); System.out.println ("Il valore è" + nowLong); }}

Quando ho eseguito quel programma, mi ha dato un valore di 972.568.255.150. Un rapido controllo con la mia calcolatrice conferma che questo numero è almeno nel campo di applicazione corretto: è un po 'meno di 31 anni, che corrisponde al giusto numero di anni tra il 1 gennaio 1970 e il giorno in cui ho scritto questo articolo. Sebbene i computer possano prosperare su numeri come il valore precedente, la maggior parte delle persone è riluttante a dire cose come "Ci vediamo su 996.321.998.346". Fortunatamente, Java fornisce un modo per convertire gli Dateoggetti in Strings, che rappresentano le date in modi più tradizionali. La DateFormatclasse, discussa nella sezione successiva, può creare Stringscon prontezza.

La classe DateFormat

Uno degli scopi di

DateFormat

classe è creare

Strings

in modo che gli esseri umani possano affrontarli facilmente. Tuttavia, a causa delle differenze linguistiche, non tutte le persone vogliono vedere una data esattamente nello stesso modo. Qualcuno in Francia potrebbe preferire vedere "25 dicembre 2000", mentre qualcuno negli Stati Uniti potrebbe essere più abituato a vedere "25 dicembre 2000". Quindi, quando un'istanza di un file

DateFormat

viene creata la classe, l'oggetto contiene le informazioni relative al particolare formato in cui la data deve essere visualizzata. Per utilizzare il formato predefinito del computer dell'utente, è possibile applicare l'estensione

getDateInstance

metodo nel modo seguente per creare il file

DateFormat

oggetto:

 DateFormat df = DateFormat.getDateInstance (); 

La DateFormatclasse si trova nel java.textpacchetto.

Conversione in una stringa

Puoi convertire un Dateoggetto in una stringa con il formatmetodo. Ciò è mostrato nel seguente programma dimostrativo:

import java.util. *; import java.text. *; public class NowString {public static void main (String [] args) {Date now = new Date (); DateFormat df = DateFormat.getDateInstance (); Stringa s = df.format (ora); System.out.println ("Oggi è" + s); }}

Il getDateInstancemetodo mostrato nel codice precedente, senza argomenti, crea un oggetto nel formato o nello stile predefinito. Java fornisce anche alcuni stili alternativi per le date, che puoi ottenere tramite il file getDateInstance(int style). Per comodità, DateFormatfornisce alcune costanti già pronte che puoi usare come argomenti nel getDateInstancemetodo. Alcuni esempi sono SHORT, MEDIUM, LONG, e FULL, che sono dimostrati nel programma qui di seguito:

import java.util. *; import java.text. *; public class StyleDemo {public static void main (String [] args) {Date now = new Date (); DateFormat df = DateFormat.getDateInstance (); DateFormat df1 = DateFormat.getDateInstance (DateFormat.SHORT); DateFormat df2 = DateFormat.getDateInstance (DateFormat.MEDIUM); DateFormat df3 = DateFormat.getDateInstance (DateFormat.LONG); DateFormat df4 = DateFormat.getDateInstance (DateFormat.FULL); Stringa s = df.format (ora); Stringa s1 = df1.format (ora); Stringa s2 = df2.format (ora); Stringa s3 = df3.format (ora); Stringa s4 = df4.format (ora); System.out.println ("(predefinito) Oggi è" + s); System.out.println ("(SHORT) Oggi è" + s1); System.out.println ("(MEDIUM) Oggi è" + s2); System.out.println ("(LONG) Today is" + s3); System.out.println ("(FULL) Oggi è" + s4); }}

Quel programma produce quanto segue:

(Predefinito) Oggi è l'8 novembre 2000 (BREVE) Oggi è l'11 / 8/00 (MEDIO) Oggi è l'8 novembre 2000 (LUNGO) Oggi è l'8 novembre 2000 (COMPLETO) Oggi è mercoledì 8 novembre 2000 

Lo stesso programma, dopo essere stato eseguito sul mio computer con le impostazioni internazionali predefinite modificate in svedese, ha visualizzato questo output:

(Default) Oggi è il 2000-nov-08 (BREVE) Oggi è il 2000-11-08 (MEDIO) Oggi è il 2000-nov-08 (LUNGO) Oggi è l'8 novembre 2000 (COMPLETO) Oggi è l'8 novembre 2000 

Da ciò, puoi vedere che in svedese i mesi dell'anno non sono in maiuscolo (anche se novembre è ancora novembre). Inoltre, tieni presente che le versioni LONGe FULLsono identiche in svedese, mentre differiscono in inglese americano. Inoltre, è interessante notare che la parola svedese per mercoledì, onsdag , non è inclusa nella FULLversione, dove la FULLversione inglese include il nome del giorno.

Tieni presente che puoi utilizzare il getDateInstancemetodo per cambiare la lingua per un fileDateFormat instance; however, in the case above, it was done on a Windows 98 machine by changing the regional settings from the control panel. The lesson here is that the default regional setting varies from place to place, which has both advantages and disadvantages of which the Java programmer should be aware. One advantage is that the Java programmer can write a single line of code to display a date, yet have the date appear in tens or even hundreds of different forms when the program is run on computers throughout the world. But that can be a disadvantage if the programmer wants just one format -- which is preferable, for example, in a program that outputs text and dates mixed together. If the text is in English, it would be inconsistent to have dates in other formats, such as German or Spanish. If the programmer relies on the default regional format, the date format will vary according to the executing computer's regional settings.

Parsing a String

You can also use the DateFormat class to create Date objects from a String, via the parse() method. This particular method can throw a ParseException error, so you must use proper error-handling techniques. A sample program that turns a String into a Date is shown below:

 import java.util.*; import java.text.*; public class ParseExample { public static void main(String[] args) { String ds = "November 1, 2000"; DateFormat df = DateFormat.getDateInstance(); try { Date d = df.parse(ds); } catch(ParseException e) { System.out.println("Unable to parse " + ds); } } } 

The parse() method is a useful tool for creating arbitrary dates. I will examine another way of creating arbitrary dates. Also, you will see how to do elementary calculations with dates, such as calculating the date 90 days after another date. You can accomplish both tasks with the GregorianCalendar class.

The GregorianCalendar class

One way to create an object representing an arbitrary date is to use the following constructor of the GregorianCalendar class, found in the java.util package:

 GregorianCalendar(int year, int month, int date) 

Note that for the month, January is 0, February is 1, and so on, until December, which is 11. Since those are not the numbers most of us associate with the months of the year, programs will probably be more readable if they use the constants of the parent Calendar class: JANUARY, FEBRUARY, and so on. So, to create an object representing the date that Wilbur and Orville Wright first flew their motored aircraft (December 17, 1903), you can use:

 GregorianCalendar firstFlight = new GregorianCalendar(1903, Calendar.DECEMBER, 17); 

For clarity's sake, you should use the preceding form. However, you should also learn how to read the shorter form, below. The following example represents the same December 17, 1903, date (remember, in the shorter form 11 represents December):

 GregorianCalendar firstFlight = new GregorianCalendar(1903, 11, 17); 

In the previous section, you learned how to turn Date objects into Strings. You will do the same again; but first, you need to convert a GregorianCalendar object to a Date. To do so, you will use the getTime() method, which GregorianCalendar inherits from its parent Calendar class. The getTime() method returns a Date corresponding to a GregorianCalendar object. You can put the whole process of creating a GregorianCalendar object, converting it to a Date, and getting and outputting the corresponding String in the following program:

 import java.util.*; import java.text.*; public class Flight { public static void main(String[] args) { GregorianCalendar firstFlight = new GregorianCalendar(1903, Calendar.DECEMBER, 17); Date d = firstFlight.getTime(); DateFormat df = DateFormat.getDateInstance(); String s = df.format(d); System.out.println("First flight was " + s); } } 

Sometimes it is useful to create an instance of the GregorianCalendar class representing the day the instance was created. To do so, simply use the GregorianCalendar constructor taking no arguments, such as:

 GregorianCalendar thisday = new GregorianCalendar(); 

A sample program to output today's date, starting with a GregorianCalendar object is:

 import java.util.*; import java.text.*; class Today { public static void main(String[] args) { GregorianCalendar thisday = new GregorianCalendar(); Date d = thisday.getTime(); DateFormat df = DateFormat.getDateInstance(); String s = df.format(d); System.out.println("Today is " + s); } } 

Note the similarities between the Date() constructor and the GregorianCalendar() constructor: both create an object, which in simple terms, represents today.

Date manipulation

The GregorianCalendar class offers methods for manipulating dates. One useful method is add(). With the add() method, you can add such time units as years, months, and days to a date. To use the add() method, you must supply the field being increased, and the integer amount by which it will increase. Some useful constants for the fields are DATE, MONTH, YEAR, and WEEK_OF_YEAR. The add() method is used in the program below to calculate a date 80 days in the future. Phileas Fogg, the central character in Jules Verne's Around the World in 80 Days, could have used such a program to calculate a date 80 days from his departure on October 2, 1872:

 import java.util.*; import java.text.*; public class World { public static void main(String[] args) { GregorianCalendar worldTour = new GregorianCalendar(1872, Calendar.OCTOBER, 2); worldTour.add(GregorianCalendar.DATE, 80); Date d = worldTour.getTime(); DateFormat df = DateFormat.getDateInstance(); String s = df.format(d); System.out.println("80 day trip will end " + s); } } 

While the example is a bit fanciful, adding days to a date is a common operation: video rentals can be due in 3 days, a library may lend books for 21 days, stores frequently require purchased items to be exchanged within 30 days. The following program shows a calculation using years:

 import java.util.*; import java.text.*; public class Mortgage { public static void main(String[] args) { GregorianCalendar mortgage = new GregorianCalendar(1997, Calendar.MAY, 18); mortgage.add(Calendar.YEAR, 15); Date d = mortgage.getTime(); DateFormat df = DateFormat.getDateInstance(); String s = df.format(d); System.out.println("15 year mortgage amortized on " + s); } } 

One important side effect of the add() method is that it changes the original date. Sometimes it is important to have both the original date and the modified date. Unfortunately, you cannot simply create a new GregorianCalendar object set equal to the original. The reason is that the two variables have a reference to one date. If the date is changed, both variables now refer to the changed date. Instead, a new object should be created. The following example will demonstrate this:

import java.util. *; import java.text. *; public class ThreeDates {public static void main (String [] args) {GregorianCalendar gc1 = new GregorianCalendar (2000, Calendar.JANUARY, 1); GregorianCalendar gc2 = gc1; GregorianCalendar gc3 = nuovo GregorianCalendar (2000, Calendar.JANUARY, 1); // Tre date tutte uguali al 1 gennaio 2000 gc1.add (Calendar.YEAR, 1); // gc1 e gc2 vengono modificati DateFormat df = DateFormat.getDateInstance (); Data d1 = gc1.getTime (); Data d2 = gc2.getTime (); Data d3 = gc3.getTime (); Stringa s1 = df.format (d1); Stringa s2 = df.format (d2); Stringa s3 = df.format (d3); System.out.println ("gc1 is" ​​+ s1); System.out.println ("gc2 is" + s2); System.out.println ("gc3 is" + s3); }}