TOC

This article is currently in the process of being translated into Italian (~28% done).

Tipi di dati:

Lavorare con Date & Ore

C# è provvisto di uno struct grandioso per lavorare con date e orari: è chiamato DateTime. Non è effettivamente un tipo di dato, ma è stato incluso in questo capitolo perché ci si troverà spesso a lavorare con date e/o orari utilizzando lo struct DateTime, talvolta tanto quanto si lavora con stringhe e numeri.

Iniziamo istanziando un nuovo oggetto DateTime:

DateTime dt = new DateTime();
Console.WriteLine(dt.ToString());

Il risultato è piuttosto noioso però: 01-01-0001 00:00:00. Questo corrisponde alla proprietà DateTime.MinValue, ma DateTime ha altre utili proprietà, la più interessante è DateTime.Now:

DateTime dt = DateTime.Now;
Console.WriteLine(dt.ToString());

Questa ci restituisce la data e ora correnti, che è spesso molto pertinente, come vedremo in alcuni dei prossimi esempi. Tuttavia, in molte situazioni, si cercherà probabilmente di rappresentare una specifica data e ora. Fortunatamente per noi, DateTime ha diversi costruttori che ci aiutano proprio in questo. Ecco un esempio:

DateTime dt = new DateTime(2042, 12, 24);
Console.WriteLine(dt.ToString());

L'ordine dei parametri in questo costruttore è Anno, Mese, Giorno, così otteniamo un oggetto con una data corrispondente alla vigilia di Natale nell'anno 2042.

DateTime - con o senza orario?

Ma che ne è dell'orario? Beh, se non se ne specifica uno, il predefinito è 00:00:00, come si può vedere dall'esempio precedente. Si può però facilmente specificare anche un orario:

DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
Console.WriteLine(dt.ToString());

Ora, DateTime ha anche un'orario, in questo caso alle 18:42. Va notato che le ore vanno specificate come un numero tra 0 e 23, poiché si usa il formato a 24 ore per l'inserimento, ma non ci si deve preoccupare se lo si vuole in formato 12 ore con AM/PM: questo si può fare facilmente in uscita, come spiegheremo più avanti.

Ci rimane una domanda: cosa fare se si è interessati solo alla parte della data? La risposta ovvia sarebbe di usare la classe Date invece di DateTime, ma effettivamente, non ne esiste una. Invece, la classe DateTime ha una proprietà Date:

DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);
DateTime date = dt.Date;
Console.WriteLine(date.ToString());

Comunquec come si vede, anche la proprietà Date è oggetto DateTime, dove la parte dell'orario è impostata a 00:00:00. Questo può sembrare un po' confuso, ma ha perfettamente senso, perché DateTime dovrebbe sempre servire da contenitore del dato che si può mostrare all'utente in diversi modi e forme. Abbiamo già usato il metodo di base ToString(), ma ci sono molti altri modi di fare uscire un oggetto DateTime

DateTime output

Getting the output of a DateTime is one of the most important aspects, but it can also be a complicated task - it really depends on your needs. So far, we have seen the very basic version of the output: The simple call to the ToString() method. This will output date and time based on the current culture of the application, which is, by default, based on the system settings. This means that if you just call the ToString() method, the date and time will be presented to the user in a way that makes sense to them no matter where in the world they are, because as you are probably aware, the format of time and especially the date varies a LOT from region to region.

If you are looking to get more control of the output, there are several ways to do that. The quickest way is to use one of the To* methods, e.g. the ToShortDateString() method:

Console.WriteLine(DateTime.Now.ToShortDateString());

This will output a short version of the date, omitting the time part completely. You can also use the ToLongDateString() method:

Console.WriteLine(DateTime.Now.ToLongDateString());

The output will vary, based on the region settings, but usually a long date includes a text representation of the month instead of a numeric representation.

If you're looking to get more control, perhaps because you want to adapt your date/time info to a specific region, you can use one of the overloads of the ToString() method, e.g. by specifying exactly which culture/region you are targeting:

var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine(DateTime.Now.ToString(usCulture.DateTimeFormat));

The CultureInfo class allows you to get an entire box of info about a language, e.g. how they write dates and time (the CultureInfo class will be covered later on in this tutorial). We can then pass this information on to the DateTime class, to let it know that we want a visual representation of the date and time to match this language. But what if we want to be even more specific about the output?

Standard Date & Time Format Strings

To gain even more control of the output, you can use the standard date & time format strings provided by the .NET framework. It's one letter, used to represent a way to display the date and/or time. For the full list, I suggest that you have a look at the documentation, but for now, here's a couple of examples:

DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);  

Console.WriteLine("Short date pattern (d): " + dt.ToString("d"));  
Console.WriteLine("Long date pattern (D): " + dt.ToString("D"));  
Console.WriteLine("Full date/time pattern (F): " + dt.ToString("F"));  
Console.WriteLine("Year/month pattern (y): " + dt.ToString("y"));

The output will look like this:

Short date pattern (d):         24-12-2042
Long date pattern (D):  24. december 2042
Full date/time pattern (F):     24. december 2042 18:42:00
Year/month pattern (y): december 2042

This gives you a bit more control of the output, but sometimes that's not enough - in those cases, you need custom format strings.

Custom Date & Time Format Strings

For full control, we have custom format strings. They are a combination of letters and special characters which you pass on to the ToString() method, to show the exact format you want for your date and/or time - this includes where you want the date/time parts, how you want them and what kind of separators you would like to use. Obviously this leaves you with a lot of options, so for the full list of available format specifiers, please check out the documentation, but let's see how it works straight away:

DateTime dt = new DateTime(2042, 12, 24, 18, 42, 0);

Console.WriteLine(dt.ToString("MM'/'dd yyyy"));
Console.WriteLine(dt.ToString("dd.MM.yyyy"));
Console.WriteLine(dt.ToString("MM.dd.yyyy HH:mm"));
Console.WriteLine(dt.ToString("dddd, MMMM (yyyy): HH:mm:ss"));
Console.WriteLine(dt.ToString("dddd @ hh:mm tt", System.Globalization.CultureInfo.InvariantCulture));

The output will look something like this:

12/24 2042
24.12.2042
12.24.2042 18:42
onsdag, december (2042): 18:42:00
Wednesday @ 06:42 PM

In general, one or several d's will get you some version of the day, one or several M's will give you the month (lowercase m is for minutes) and a number of y's will give you the year. To fully understand what these format specifiers do, I still suggest that you have a look at the documentation, but hopefully the above example has given you a good idea of just how powerful the custom format strings are.

Parsing dates

So far, we have worked with dates defined directly in code, but you will probably quickly run into a situation where you need to work with a date specified by the user. This is a surprisingly complicated subject because there are so many ways of writing a date. The .NET framework can help you with this, because it supports all the cultures, as illustrated in previous examples, but you still need to help the user specify the date in the format you expect. After that, you can use the Parse() method to turn a user-specified string into a DateTime object, like this:

var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine("Please specify a date. Format: " + usCulture.DateTimeFormat.ShortDatePattern);
string dateString = Console.ReadLine();
DateTime userDate = DateTime.Parse(dateString, usCulture.DateTimeFormat);
Console.WriteLine("Date entered (long date format):" + userDate.ToLongDateString());

This example is actually pretty cool because it shows just how much the .NET framework can help us, as long as we have an instance of the CultureInfo class that we want to use (US English in this case - and don't worry, we will discuss the CultureInfo class in much greater detail later on). As soon as we have this, we use it for letting the user know which format we expect. Then we use it again in the 4th line, to actually parse the input. In the last line, we output the user-specified date, this time just using the format specified by the system.

However, be aware that the Parse() method is very strict - if the user doesn't enter the date in the expected format, it will throw an exception. For that reason, it's usually a good idea to use the TryParse() method instead - it does the exact same thing, but it allows you to check if the date could be parsed or not, and it doesn't throw an exception. Here's a revised version of the previous example:

var usCulture = new System.Globalization.CultureInfo("en-US");
Console.WriteLine("Please specify a date. Format: " + usCulture.DateTimeFormat.ShortDatePattern);
string dateString = Console.ReadLine();
DateTime userDate;
if (DateTime.TryParse(dateString, usCulture.DateTimeFormat, System.Globalization.DateTimeStyles.None, out userDate))
    Console.WriteLine("Valid date entered (long date format):" + userDate.ToLongDateString());
else
    Console.WriteLine("Invalid date specified!");

Summary

Working with dates and time is very important but also very complex. Lucky for us, the .NET framework is there to help us in almost all situations with the brilliant DateTime class.

This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!