Are the Date, Time, and Datetime Classes Necessary

Are the Date, Time, and DateTime classes necessary?

DateTime is a subclass of Date, so whatever you can do with Date can be done with DateTime. But as tadman and steenslag point out, DateTime is slower. See steenslag's answer for how much slower it is.

With respect to DateTime vs, Time, I found something here:

Time is a wrapper around Unix-Epoch.
Date (and DateTime) use rational and a "day zero" for storage. So Time is faster but the upper and lower bounds are tied to epoch time (which for 32bit epoch times is something around 1970-2040...while Date (and DateTime) have an almost infinite range but are terribly slow.

In short, DateTime is an all around superstar, and should be preferred in general, but if you want to optimize to the last bit, using Time can improve performance.

# How to use the DateTime class (Dealing with Conversions, Formatting, Diffs, and Time zones)

Most of the below information can be gotten from various parts of PHP's documentation of the DateTime class. However, this answer is formatted in a way that should answer most people's questions regarding the DateTime class, and should apply to most of its use cases.

If you are trying to do something more advanced with Dates/Times such as creating a DateTime wrapper, using immutable DateTime instances, or something else that's specific to your applications needs I highly suggest you checkout the full Date and Time documentation.


1. How do I convert a string to a modifiable date/time?

One of the hardest things to do in programming is to try and make end-user input usable. However, when it comes to dates and times, the DateTime class makes this practically child's play.

How

DateTime's constructor uses a powerful parser that accepts most widely known formats including relative formats.

$datetime = new DateTime($datetime_string);

From there you can use any of the following methods to modify the time:

  • $datetime->modify() - Alters the timestamp (works great with relative formats!)
  • $datetime->add() - Adds an amount of days, months, years, hours, minutes and seconds to a DateTime object
  • $datetime->sub() - Subtracts an amount of days, months, years, hours, minutes and seconds from a DateTime object
  • $datetime->setDate() - Sets the date
  • $datetime->setISODate() - Sets the ISO date
  • $datetime->setTime() - Sets the time
  • $datetime->setTimestamp() - Sets the date and time based on an Unix timestamp (great for dealing with absolute times across time zones!)

To see the full list of formats that DateTime::__construct() supports check out: Supported Date and Time Formats.

Example - Interpreting End-User Input

Lets say you have form that allows users to say what day they want to make an appointment, but this input is not a date picker with a forced format, but is instead a plain text input.

A typical end-user will put something like these in that input and a typical programmer will respond in the following ways when asked to support it:

  • 12/31/2000 - "OK"
  • 2000-12-31 - "Sure"
  • Today - "Um, I guess we could support that?"
  • Tomorrow - "I guess we should support that too."
  • wednesday next week - "No."

After a while you either force a specific format (which you should always do anyway) or weep at your poor form design. However, DateTime allows all of these as valid inputs and interprets them flawlessly.

// 2000-12-31 00:00:00.000000
new DateTime('12/31/2000');

// 2000-12-31 00:00:00.000000
new DateTime('2000-12-31');

// 2000-12-31 00:00:00.000000
new DateTime('Today');

// 2001-01-01 00:00:00.000000
new DateTime('Tomorrow');

// 2001-01-03 00:00:00.000000
new DateTime('wednesday next week');

However, like most things the DateTime class is not perfect, and doesn't support every format. Which is why you should always use try ... catch blocks with DateTime and confirm with your end-user that the date you interpreted is what the end-user desired. One great example is European date formats:

try {
new DateTime('31/12/2000');
} catch (Exception $e) {
echo $e->getMessage();
}

Output:

DateTime::__construct(): Failed to parse time string (31/12/2000) at position 0 (3): Unexpected character

Example - Modifying A Date/Time

You can adjust any date/time easily with the $datetime->modify() method:

$datetime = new DateTime('2001-01-01');

// 2001-01-04 00:00:00.000000
$datetime->modify('+3 days');

// 2001-02-04 00:00:00.000000
$datetime->modify('+1 month');

// 2001-02-03 23:59:00.000000
$datetime->modify('-60 seconds');

// 2001-02-02 00:00:00.000000
$datetime->modify('yesterday');

// 2001-02-02 18:00:00.000000
$datetime->modify('6pm');

The $datetime->modify() method is the easiest way to modify any instance of DateTime.

However, due to parsing it is somewhat inefficient. If you are modifying 1000's of dates/times and you need better performance, then use add(), sub(), setDate(), setISODate(), setTime(), and setTimestamp() instead of modify().

$datetime = new DateTime('2001-01-01');

// 2001-06-01 00:00:00.000000
$datetime->setDate(2001, 6, 1);

// 2001-06-01 06:30:00.000000
$datetime->setTime(6, 30, 0);

// No sane person should ever do the below when they could just add 10,000
// seconds, but it's a good way to test how fast your system will handle
// updating DateTime.
$timestamp = $datetime->getTimestamp();
foreach (range(1, 10000) as $i) {
$timestamp++;
$datetime->setTimestamp($timestamp);
}
// 2001-06-01 09:16:40.000000

2. How do I format a date/time string?

It's common that you need to take 1 date/time string and format it as another date/time string, or even just take and existing date/time and update it. The DateTime class makes this simple as well.

How

DateTime has the method format() which returns the date/time as a formatted string.

$datetime = new DateTime;
$format = 'Y-m-d H:i:s';
echo $datetime->format($format);

We are only going to use a small subset of the formatting options available in these examples, so I highly encourage you to checkout the documentation on formatting dates/times as well as the predefined DateTime constants.

Notice: Be aware that if you attempt to escape a character that could be PHP string escape character you may get unexpected results.

Incorrect Result

// output: Da   e 2000-12-31
echo $datetime->format("\D\a\t\e\: Y-m-d").PHP_EOL;

Correct Result

// output: Date 2000-12-31
echo $datetime->format("\D\a\\t\e\: Y-m-d").PHP_EOL;

// output: Date 2000-12-31
echo $datetime->format('\D\a\t\e\: Y-m-d').PHP_EOL;

Examples

These are some common formats that you may need:

SQL Dates/Times

// output: 2000-12-31
echo $datetime->format('Y-m-d').PHP_EOL;

// output: 23:59:59
echo $datetime->format('H:i:s').PHP_EOL;

// output: 2000-12-31 23:59:59
echo $datetime->format('Y-m-d H:i:s').PHP_EOL;

End-User Readable Dates/Times

// output: 12/31/2000
echo $datetime->format('n/j/Y').PHP_EOL;

// output: 11:59pm
echo $datetime->format('g:ia').PHP_EOL;

// output: 12/31/2000 at 11:59pm
echo $datetime->format('n/j/Y \a\t g:ia').PHP_EOL;

// output: Sunday the 31st of December 2000 at 11:59:59 PM
echo $datetime->format('l \t\h\e jS \o\f F Y \a\t g:i:s A').PHP_EOL;

Dates/Times With Time zones

date_default_timezone_set('America/New_York');
$datetime = new DateTime('2000-12-31 23:59:59');

// output: 2000-12-31 23:59:59 America/New_York
echo $datetime->format('Y-m-d H:i:s e').PHP_EOL;

// output: 2000-12-31 23:59:59 EST
echo $datetime->format('Y-m-d H:i:s T').PHP_EOL;

// output: 2000-12-31 23:59:59 -0500
echo $datetime->format('Y-m-d H:i:s O').PHP_EOL;

3. How do I get the difference between 2 times?

It is common to need to know the difference in time between 2 dates/times. With DateTime there are actually 3 different ways to achieve this, and which one you will want to use will depend on your needs.

How (with Examples)

Scenario 1: You only need to know if $datetime1 is greater than, less than, or equal to $datetime2

In this case, you can simply directly compare the instances of DateTime.

$datetime1 = new DateTime;
sleep(1);
$datetime2 = new DateTime;

var_dump($datetime1 > $datetime2); // FALSE
var_dump($datetime1 < $datetime2); // TRUE
var_dump($datetime1 == $datetime2); // FALSE

Scenario 2: You need the difference between $datetime1 and $datetime2 expressed as broken-down years/months/days/etc.

This will work for most cases, however the DateInterval instance you get back from $datetime->diff() has its own "gotchas" and may not work for your specific use case.

$datetime1 = new DateTime('2000-01-01 00:00:00.000000');
$datetime2 = new DateTime('2001-02-03 04:05:06.789012');
$diff = $datetime1->diff($datetime2);

// output: 1 Years, 1 Months, 2 Days, 4 Hours, 5 Minutes, 6 Seconds
echo $diff->format('%y Years, %m Months, %d Days, %h Hours, %i Minutes, %s Seconds');

Scenario 3: You need the difference between $datetime1 and $datetime2 expressed in another way.

This will work in any context at the cost of a little extra code.

$interval   = 60 * 60 * 24; // 1 day in seconds
$datetime1 = new DateTime('2000-01-01');
$datetime2 = new DateTime;
$diff = $datetime2->getTimestamp() - $datetime1->getTimestamp();

// output: It has been 6956 days since 2000-01-01!
printf('It has been %s days since %s!', floor($diff / $interval), $datetime1->format('Y-m-d'));

4. How do I account for time zones?

When it comes to dealing with time in programming, by far the worst part is dealing with time zones. Fortunately, this is something else that the DateTime class handles gracefully.

How

DateTime's constructor allows you to specify the source time zone in either the date/time string or as the 2nd Argument. After that, just set a new timezone with $datetime->setTimezone() and DateTime will take care of the rest.

// These 2 lines are functionally identical
$datetime = new DateTime('2001-01-01 00:00:00', new DateTimeZone('UTC')); // recommended, may be faster
$datetime = new DateTime('2001-01-01 00:00:00 UTC');

$datetime->setTimezone(new DateTimeZone('EST'));

I recommend checking out the full list of PHP's supported time zones as well as the docs on the DateTimeZone class.

Example

Lets say you want to show your end-users the time your customer support line opens in their time zone. With DateTime the code would look something like this:

$support_opens      = new DateTime('08:00:00', new DateTimeZone('America/New_York'));
$customer_timezones = array('America/New_York', 'America/Chicago', 'America/Denver', 'America/Phoenix', 'America/Los_Angeles', 'America/Anchorage', 'America/Adak', 'Pacific/Honolulu');

echo "Today we open at the following times:".PHP_EOL;
foreach ($customer_timezones as $timezone) {
$support_opens->setTimezone(new DateTimeZone($timezone));
echo '* '.$support_opens->format('g:ia \f\o\r \t\h\e e').' time zone'.PHP_EOL;
}

Output:

Today we open at the following times:
* 8:00am for the America/New_York time zone
* 7:00am for the America/Chicago time zone
* 6:00am for the America/Denver time zone
* 6:00am for the America/Phoenix time zone
* 5:00am for the America/Los_Angeles time zone
* 4:00am for the America/Anchorage time zone
* 3:00am for the America/Adak time zone
* 3:00am for the Pacific/Honolulu time zone

Notice: If you supply a time zone in both the date/time string and as the second argument, the argument time zone will be ignored.

$datetime = new DateTime('2001-01-01 00:00:00 EST', new DateTimeZone('UTC'));

// output: 2001-01-01 00:00:00 EST
echo $datetime1->format('Y-m-d H:i:s');

Should I use the datetime or timestamp data type in MySQL?

Timestamps in MySQL are generally used to track changes to records, and are often updated every time the record is changed. If you want to store a specific value you should use a datetime field.

If you meant that you want to decide between using a UNIX timestamp or a native MySQL datetime field, go with the native DATETIME format. You can do calculations within MySQL that way
("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)") and it is simple to change the format of the value to a UNIX timestamp ("SELECT UNIX_TIMESTAMP(my_datetime)") when you query the record if you want to operate on it with PHP.

import datetime v.s. from datetime import datetime

Your trouble is that you have some code that is expecting datetime to be a reference to the datetime module and other code that is expecting datetime to be a reference to the datetime class. Obviously, it can't be both.

When you do:

from datetime import datetime
import datetime

You are first setting datetime to be a reference to the class, then immediately setting it to be a reference to the module. When you do it the other way around, it instead ends up being a reference to the class. Last assignment "wins."

You need to rename one of these references. For example:

import datetime as dt
from datetime import datetime

Then you can change references in the form datetime.xxxx that refer to the module to dt.xxxx.

Or else just import datetime and change all references to use the module name. In other words, if something just says datetime(...) you need to change that reference to datetime.datetime.

Python has a fair bit of this kind of thing in its library, unfortunately. If they followed their own naming guidelines in PEP 8, the datetime class would be named Datetime and there'd be no problem using both datetime to mean the module and Datetime to mean the class.

DateTime class vs. native PHP date-functions

If your worry is that creating a class instance is expensive and that it'll hinder performance, then I'm afraid you're barking at the wrong tree. One should never consider whether to use proven OO approach where it makes sense. If it makes sense to use DateTime class in order to perform certain date calculations, then use it. It's not expensive to the point where your app will feel it, unless you do something crazy such as creating 1 million DateTime objects.

Reason why DateTime is great is because it alleviates the worry of daylight savings by specifying the time zone when creating the object. It's also easy to obtain differences between dates or obtain intervals between different objects. It basically cuts down the amount of worry and coding required (but I will admit it is wrong sometimes, hopefully it'll get addressed in 5.4 release of PHP).

Bottom line - I'd always use it.

Which date class should I use in Java 8?

Each one of the Date classes are for specific purposes:

  • If you want to use your Date in an SQL/JDBC context, use the java.sql.Timestamp.

  • java.util.Date is the old Java API, it is not thread safe, you can difficultly handle time zoning, and on the top of all, it is poorly designed: one simple uniformity is that months start from 1 while days start from 0.

  • java.time.LocalDateTime is an immutable date-time object that represents a date-time, often viewed as year-month-day-hour-minute-second, which you need exactly.

  • java.time.ZonedDateTime class stores all date and time fields, so you can use it to deal with values like:
    27th January 1990 at 15:40.30.123123123 +02:00 in the Europe/Paris time-zone.

To do your task, the ZonedDateTime class handles conversion from the local time-line of LocalDateTime to the instant time-line of Instant(which models a single instantaneous point on the time-line). The difference between the two time-lines, represented by a ZoneOffset, is the offset from UTC/Greenwich.

To calculate duration and period: there is the java.time.Duration which is a time-based amount of time, such as '20.5 seconds', and java.time.Period, which is a date-based amount of time (like: 26 years, 2 months and 2 days).

To get max and min dates, you can use the Java 8 lambdas in something like:

Date maxDate = list.stream().map(yourInstance -> yourInstance.date).max(Date::compareTo).get();
Date minDate = list.stream().map(yourInstance -> yourInstance.date).min(Date::compareTo).get();

What does '...' in time(...) means in timedate class in python?

In your code you are trying to get the time from the time object directly, so you need to do:

from datetime import datetime
t = datetime.now().time()
print ("The current time is ", t)

# The current time is 18:11:56.271907

The class method datetime.now() is described here

Return the current local date and time. If optional argument tz is
None or not specified, this is like today(), but, if possible,
supplies more precision than can be gotten from going through a
time.time() timestamp (for example, this may be possible on platforms
supplying the C gettimeofday() function).

If you want to use the function time() directly you need to change your import:

import datetime
print(datetime.time())

# datetime.time(0, 0)

The import from datetime import datetime means that you are importing the object datetime from the module datetime, into this object you have the nested object time <method 'time' of 'datetime.datetime' objects>.

The datetime module is probably particularly confusing because the module also includes a datetime class, so datetime.datetime refers to the datetime class within the datetime module. If you do from datetime import datetime, you're only importing the datetime class, so when you refer to datetime in your code, it's referring to the datetime class, not the whole datetime module.

Using the import import datetime you are importing the module directly, where is located the function time() that use the class <class 'datetime.time'>

Reference to the time class is here

An idealized time, independent of any particular day, assuming that
every day has exactly 246060 seconds (there is no notion of “leap
seconds” here). Attributes: hour, minute, second, microsecond, and
tzinfo.

Reference to the datetime class nested into the datetime module is here

A combination of a date and a time. Attributes: year, month, day,
hour, minute, second, microsecond, and tzinfo.

Inside this reference you can find the datetime.time() instance method

Return time object with same hour, minute, second, microsecond and
fold. tzinfo is None. See also method timetz().



Related Topics



Leave a reply



Submit