What’s The Best Date Format?

Share this article

Key Takeaways

  • The best date format for programming purposes is ISO 8601 (2004) in UTC. This format stores a complete date and time, is compatible with JavaScript’s new Date constructor, uses a fixed timezone for comparison, is sortable without additional conversion, avoids parsing ambiguities, and provides a level of human-readability.
  • It is not necessary to store dates and times in different timezones as every timestamp has a UTC equivalent. All timestamps should be recorded in UTC and converted to local-time only when outputting to the client. This allows for a common frame of reference for programatically comparing dates without losing any information needed for internationalization.
  • To use the ISO format in PHP, there isn’t a pre-defined constant or token for creating this precise format. The simplest method is to compile it manually, from individual date and time components, using the gmdate function to get UTC. For example: $timestamp = gmdate(‘Y-m-dTH:i:sZ’);. This timestamp can then be used on the client as the timestamp argument to new Date.

When it comes to displaying dates and times, there’s no single format that works for every situation. With such wide international and regional variation in formatting, and so many different situations in which dates and times are used, every case is unique — from verbose and lyrical sentences like Monday the 21st of March at 12:18am (EST), to enigmatic and compact output like Today.

But when it comes to working with dates programatically — storing, comparing and sorting with them — there’s really no need for such a wide variety of formats. Indeed, it makes much more sense to unify the use of programatic dates, and use the same format for everything.

So what’s the best format to use?

It would need to tick several boxes — think of these as ‘must-have’ features:

  • it stores a complete date and time, providing all the raw information we need to create any other format
  • we can use it as the input for creating and converting dates — eg. it must be compatible with the timestamp argument to JavaScript’s new Date constructor
  • it always use the same, fixed timezone, to provide a frame of reference for comparison

Over and above those core requirements, there’s a few ‘would-be-nice’ features:

  • its format is natively sortable without additional conversion (ie. if used as a filename, it would create a chronological sort-order)
  • it has no internal whitespace — to avoid parsing ambiguities such as excessive contiguous space, or tab/space difference
  • it provides at least some level of human-readability, chiefly for programmers’ sake
  • it should give us at least some ‘free’ information, ie. values such as the year or the hour being easily obtained by string parsing, without having to create and parse new date objects every time

What about timezones?

It’s not really necessary to store dates and times in different timezones — every given timestamp has a UTC/GMT equivalent. So the simplest thing to do is record all timestamps in UTC, converting them to local-time only when outputting to the client. This gives us a common frame of reference for programatically comparing dates, without losing any information we need for internationalization.

JavaScript dates are always local

Since JavaScript evaluates on the client, it uses the client’s clock as a time reference. So any timestamp passed through the Date constructor is automatically converted to the user’s local time.

My ultimate recommendation

In the past, until I actually sat down and though this out seriously, I generally used the RFC 2822 date format (eg. "Mon, 21 Mar 2011 00:18:56 +0000") — mostly because it’s so easy to generate in PHP (defined by the formatting character "r"), and it ticks all the must-have boxes. But it’s not natively sortable, and not the choice I ultimately arrived at:

My ultimate recommendation is ISO 8601 (2004) in UTC.

There are several variations of this format, and the one I’ve specifically chosen uses the date-time delimiter "T" and the timezone designator "Z" (which designates UTC); other variations use a space as the delimiter, or designate the timezone as "+00:00", but I don’t recommend either of those — the space makes it incompatible with new Date in Firefox, and the longer more complex timezone designator is simply unnecessary.

So the timestamps we’re talking about look like this: "2011-03-21T00:18:56Z"

Although this format is not as easy to generate as others (see How to use the ISO format below), it does tick all the other boxes, both the must-haves and would-be-nices. And it also provides a number of additional benefits — bonus features, you might say, which solidify its status as the ideal choice:

  • it’s always a constant length
  • it’s the format used natively by JSON (eg. in JavaScript, if you pass a Date object through JSON.stringify, it’s converted to this format)
  • it’s the format and profile recommended by the W3C
  • it’s compatible with the DATESTAMP column-type in SQL, albeit as ‘relaxed’ syntax
MySQL DATESTAMP gotcha

An issue I’ve discovered with PHP and MySQL, is that when a timestamp in this format stored in a DATESTAMP column, its "T" delimiter is replaced with a space, and its "Z" token is removed, converting it to the strict DATESTAMP format. But this is not what we want, and not acceptable.

All I do to fix this is re-convert the output, but I’d love to hear of a more permanent solution — a MySQL config option or something?

How to use the ISO format

PHP doesn’t have a pre-defined constant or token for creating this precise format, although the formatting-token "c" creates one very similar (same standard, different variant). We could then convert the differences with string-replacement; but I reckon the simplest thing to do is just compile it manually, from individual date and time components, using the gmdate function to get UTC:

$timestamp = gmdate('Y-m-dTH:i:sZ');

Once we have our timestamp, we can use it on the client as the timestamp argument to new Date. For example, we could first output the raw timestamp to static HTML:

<dl class="listing">
    <dt>Date created:</dt>
    <dd id="listing-timestamp"><?php echo gmdate('Y-m-dTH:i:sZ'); ?></dd>
</dl>

And then use JavaScript to convert it to a re-formatted locale-specific date and time, eg:

var dd = document.getElementById("listing-timestamp");
    
dd.innerHTML = new Date(dd.innerHTML).toLocaleString();

Of course the mechanics of passing timestamps around between the client and server will vary tremendously with the application. A PHP script may output the timestamp directly to server-generated JavaScript; it might be the response of an Ajax request, or it might be written to static HTML, like the example above. However it’s done, the most common use-case is likely to be server-generated timestamps which output to the client for conversion, and the processes I’ve described so far will do that. But what of other cases?

You might be working entirely on the server, and only outputting fully-formatted, user-ready dates. PHP provides numerous ways of internally converting one date to another, but the one I find most straightforward is to pass the timestamp through strtotime (to convert it to a numeric value), and then use that as the second argument to date:

$rfcdate = date('r', strtotime($timestamp));

Conversely, you might be generating and converting entirely on the client, and in that case you’ll need a way of generating the timestamp in JavaScript. The following function will do the job:

function getTimestamp()
{
    var dateobj = new Date();
    dateobj.setTime(dateobj.getTime() + (dateobj.getTimezoneOffset() * 60000));
    
    var datetime = {
        date : [
            dateobj.getFullYear(),    
            dateobj.getMonth() + 1,    
            dateobj.getDate()
            ],
        time : [
            dateobj.getHours(),        
            dateobj.getMinutes(),        
            dateobj.getSeconds()
            ]
        }; 
    
    for(var key in datetime)
    {
        if(!datetime.hasOwnProperty(key)) { continue; }
        
        for(var i in datetime[key])
        {
            if(!datetime[key].hasOwnProperty(i)) { continue; }
            
            var n = datetime[key][i];
            datetime[key][i] = (n < 10 ? '0' : '') + n; 
        }
    }
    
    return datetime.date.join('-') + 'T' 
         + datetime.time.join(':') + 'Z';
}

The timestamp it produces can then be passed to new Date, and processed in locale-time from there:

var timestamp = getTimestamp();
    
...
    
var rfcdate = new Date(timestamp).toString();

Frequently Asked Questions (FAQs) about Date Formats

Why is the ISO 8601 date format considered the best?

The ISO 8601 date format is considered the best because it eliminates ambiguity and confusion. It is an international standard that follows the format “YYYY-MM-DD”. This format is universally understood and is not subject to regional variations. It is also easily sortable in ascending or descending order, which is particularly useful in data analysis and computer programming.

What are the differences between American and European date formats?

The main difference between American and European date formats is the order of the day and month. In the United States, the date format follows the month/day/year order. In contrast, European countries typically use a day/month/year format. This difference can lead to confusion when dates are written in numerical form.

How can I parse any date format in Java?

Java provides several classes to handle date and time. The SimpleDateFormat class is commonly used to parse and format dates. You can specify the desired date format using pattern strings. For example, to parse a date in the format “dd-MM-yyyy”, you can use the following code:

SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Date date = sdf.parse("01-01-2022");

What are the different date format types in Oracle?

Oracle supports a variety of date format models. Some of the most common ones include “DD” for day of the month, “MM” for month, “YYYY” for 4-digit year, “HH24” for hour of the day (0-23), “MI” for minute, and “SS” for second. You can combine these elements in various ways to create custom date formats.

Why is it important to standardize date formats?

Standardizing date formats is crucial to avoid misunderstandings and errors, especially in international communications or computer systems. Different regions have different conventions for writing dates, which can lead to confusion. By using a standardized format, such as ISO 8601, you can ensure that dates are understood correctly by everyone.

How can I convert a date to a different format?

The process of converting a date to a different format depends on the programming language or software you are using. In general, you would need to parse the date in its original format, then output it in the desired format. Most programming languages provide built-in functions or libraries to handle date parsing and formatting.

What is the best date format for sorting data?

The best date format for sorting data is “YYYY-MM-DD”. This format allows dates to be sorted in chronological order when sorted as strings, because the most significant units (the year) come first, followed by the month and day.

How can I handle date formats in different languages?

Many programming languages and software tools provide localization features to handle date formats in different languages. For example, in Java, you can use the DateFormat class along with a Locale object to format dates according to a specific locale.

What is the difference between 12-hour and 24-hour time formats?

The 12-hour time format divides the day into two periods: AM (from midnight to just before noon) and PM (from noon to just before midnight). The 24-hour format, also known as military time, runs from 0 to 23 hours. The 24-hour format is commonly used in many countries and in various sectors such as military, aviation, computing, and transportation.

How can I validate a date format?

You can validate a date format by parsing the date string with the expected format. If the parsing succeeds without errors, the format is valid. If it fails, the format is invalid. Most programming languages provide functions or libraries to parse dates and handle errors.

James EdwardsJames Edwards
View Author

James is a freelance web developer based in the UK, specialising in JavaScript application development and building accessible websites. With more than a decade's professional experience, he is a published author, a frequent blogger and speaker, and an outspoken advocate of standards-based development.

javascriptPHP
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week