Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of a naive datetime

Tags:

python

Coming from C#, I've learned to always be aware of time-zones when handling date/time. Python has proper timezone handling and useful helpers like datetime.utcnow, which makes working with date/time straight forward. But, when reading in the python docs, I noticed that there is something called a "naive" datetime instance. As far as I can see, this is just a datetime without any timezone.

What is the use-case for a naive datetime? Isn't a datetime without a time-zone pretty useless? And why doesn't datetime.now() return a datetime in the current locale (like .NET)?

I'm sure I'm missing something crucial, so I hope someone can shed some light on this.

like image 538
zeebonk Avatar asked Jun 18 '14 09:06

zeebonk


People also ask

What is a naive datetime?

We call them "naive" because this datetime representation does not have a time zone. This means the datetime may not actually exist in certain areas in the world even though it is valid. For example, when daylight saving changes are applied by a region, the clock typically moves forward or backward by one hour.

What is naive and aware datetime?

If a datetime object has time zone information, then it will be aware. Otherwise, it will be naive. In the case of a naive datetime object, tzinfo will be None and time will be in UTC(+00:00).

How do I know if datetime is naive?

A naive datetime object contains no timezone information. The easiest way to tell if a datetime object is naive is by checking tzinfo. tzinfo will be set to None of the object is naive. To make a datetime object offset aware, you can use the pytz library.

What is datetime used for?

The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in ' YYYY-MM-DD hh:mm:ss ' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59' . The TIMESTAMP data type is used for values that contain both date and time parts.


2 Answers

What is the point of a naive datetime

A naive datetime is very useful!

In some cases you don't know or don't want to specify a timezone.

Imagine that you are parsing an ancient external program log file, and you don't know what timezone the datetimes are in - your best bet is leave them as-is. Attaching a timezone to such datetimes would be wrong and could lead to errors, as you'd be pretending to have information you don't actually have.


And why doesn't datetime.now() return a datetime in the current locale (like .NET)?

datetime.now() does return a value in the current locale timezone, but it doesn't have a timezone associated with it (a tzinfo attribute), which is probably what you meant. Notice that the same is true for utcnow(), both return naive datetimes

The rationale for not including timezone support in the datetime module is alluded to in the docs:

Note that no concrete tzinfo classes are supplied by the datetime module. [...] The rules for time adjustment across the world are more political than rational, and there is no standard suitable for every application.

If you included timezone support in the standard library, you'd get wrong results somewhere in the world.

Timezones are a political concept and change several times a year, globally. The life expectancy of the locally installed python standard library is (generally) much larger than the correctness of timezone data.


What should I do to support timezones

Disclaimer: you should just use UTC in almost all cases. Local timezones should only be used as a last step when showing values to the user.

To use timezones, your program should depend on the pytz package, which gives you proper timezone suport.

from time import tzname
from pytz import timezone
from datetime import datetime
timezone(tzname[0]).localize(datetime.now())

Remember that your program or the local system administrator will need to keep the package up to date.

like image 166
loopbackbee Avatar answered Nov 06 '22 19:11

loopbackbee


What is the use-case for a naive datetime?

Python does not allocate space for the pointer to the timezone object if the datetime object is naive:

/* ---------------------------------------------------------------------------
 * Basic object allocation:  tp_alloc implementations.  These allocate
 * Python objects of the right size and type, and do the Python object-
 * initialization bit.  If there's not enough memory, they return NULL after
 * setting MemoryError.  All data members remain uninitialized trash.
 *
 * We abuse the tp_alloc "nitems" argument to communicate whether a tzinfo
 * member is needed.  This is ugly, imprecise, and possibly insecure.
 * tp_basicsize for the time and datetime types is set to the size of the
 * struct that has room for the tzinfo member, so subclasses in Python will
 * allocate enough space for a tzinfo member whether or not one is actually
 * needed.  That's the "ugly and imprecise" parts.  The "possibly insecure"
 * part is that PyType_GenericAlloc() (which subclasses in Python end up
 * using) just happens today to effectively ignore the nitems argument
 * when tp_itemsize is 0, which it is for these type objects.  If that
 * changes, perhaps the callers of tp_alloc slots in this file should
 * be changed to force a 0 nitems argument unless the type being allocated
 * is a base type implemented in this file (so that tp_alloc is time_alloc
 * or datetime_alloc below, which know about the nitems abuse).
 */

static PyObject *
time_alloc(PyTypeObject *type, Py_ssize_t aware)
{
    PyObject *self;

    self = (PyObject *)
        PyObject_MALLOC(aware ?
                        sizeof(PyDateTime_Time) :
                sizeof(_PyDateTime_BaseTime));
    if (self == NULL)
        return (PyObject *)PyErr_NoMemory();
    PyObject_INIT(self, type);
    return self;
}

How you use naive datetime objects is up to you. In my code I use naive datatime objects as:

  1. As if they had UTC timezone associated with them, or
  2. I don't care what the timezone is at all.
like image 34
Maxim Egorushkin Avatar answered Nov 06 '22 19:11

Maxim Egorushkin