{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Module 6: Time \n", "## Chapter 15 from the Alex DeCaria textbook\n", "\n", "Handling time is critical in environmental programming. Fortunately the python datetime module helps but the approach takes a bit to keep straight\n", "\n", "\n", "**Before starting:** Make sure that you open up a Jupyter notebook session using OnDemand so you can interactively follow along with today's lecture! Also be sure to copy this Jupyter Notebook and then create a new file with the name using the current date to use to experiment with the syntax. \n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# datetime module\n", "\n", "There are several ways to use the datetime module. \n", "We'll avoid some of the jargon about objects, so think of classes described in Chapter 15 as repositories that contain ways to manage groupings of objects (go back to Chapter 9 if really interested).\n", "\n", "- date: defines time in terms of days, months, years\n", "- time: defines time in relative terms without respect to a spefici day/month/year\n", "- datetime: handles both of the aforementioned (the one used the most)\n", "- timedelta: datetime differences\n", "- timezone: timezones (critical for environmental data)\n", "\n", "We can either send values into these specific classes or extract values from them" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import datetime as dt\n", "#note the following can be confusing. dt.datetime now refers to datetime.datetime, dt.timedelta refers to datetime.timedelta\n", "from datetime import datetime, timedelta, timezone\n", "import zoneinfo\n", "import numpy as np\n", "import pandas as pd" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-10-20 14:14:00.333422\n", "\n" ] }, { "data": { "text/plain": [ "datetime.datetime(2022, 10, 20, 14, 14, 0, 333422)" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#current time\n", "\n", "right_now = dt.datetime.now()\n", "#print organizes the time in a conventional format\n", "print(right_now)\n", "#what is a class? see pages 121-122\n", "print(type(right_now))\n", "#but the datetime.datetime object right_now has a defined structure\n", "right_now" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-10-20 20:14:00.358634\n" ] } ], "source": [ "# we do a lot in UTC time\n", "right_now_utc = dt.datetime.utcnow()\n", "print(right_now_utc)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-10-20 14:14:00.378659-06:00\n" ] } ], "source": [ "# what about in mt?\n", "MT = zoneinfo.ZoneInfo(\"US/Mountain\")\n", "right_now_mt = dt.datetime.now(MT)\n", "print(right_now_mt)\n" ] }, { "cell_type": "raw", "metadata": {}, "source": [] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2022-10-20 10:14:00.358634-10:00\n" ] } ], "source": [ "#what about hawaii?\n", "HT = zoneinfo.ZoneInfo(\"US/Hawaii\")\n", "date_HI= right_now_utc.replace(tzinfo=timezone.utc).astimezone(tz=HT)\n", "print(date_HI)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "## enter a date interactively. The input text shows how to do it manually in this case. Commas between values\n", "day_string_1 = input('Enter a 4-digit year , month (1-12) , day (1-31): ')\n", "print(day_string_1)\n", "# but this is a string\n", "print(type(day_string_1))\n", "#convert to integers\n", "day_1 = np.fromstring(day_string_1, dtype=int, sep=',')\n", "print(day_1)\n", "#what is the type of day_1\n", "print(type(day_1))\n", "#create a datetime object\n", "my_day_1 = dt.datetime(day_1[0],day_1[1],day_1[2])\n", "print(my_day_1)\n", "print(type(my_day_1))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#A simpler way to deal with times is to format strings\n", "# datetime.strptime() creates a datetime object from a string \n", "#representing a date and time using a specific format string.\n", "#See Table 15.1 pg 215 and strftime.org" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Code | Example | Description \n", "---- | ---- | -----\n", " %a | Sun | Weekday as locale’s abbreviated name. \n", " %A | Sunday | Weekday as locale’s full name.\n", " %w | 0 | Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.\n", " %d | 08 | Day of the month as a zero-padded decimal number.\n", " %b | Sep | Month as locale’s abbreviated name.\n", " %B | September | Month as locale’s full name.\n", " %m | 09 | Month as a zero-padded decimal number.\n", " %y | 13 | Year without century as a zero-padded decimal number.\n", " %Y | 2013 | Year with century as a decimal number.\n", " %H | 07 | Hour (24-hour clock) as a zero-padded decimal number.\n", " %I | 07 | Hour (12-hour clock) as a zero-padded decimal number.\n", " %p | AM | Locale’s equivalent of either AM or PM.\n", " %M | 06 | Minute as a zero-padded decimal number.\n", " %S | 05 | Second as a zero-padded decimal number.\n", " %z | +0000 | UTC offset in the form ±HHMM[SS[.ffffff]] \n", " %Z | UTC | Time zone name \n", " %j | 251 | Day of the year as a zero-padded decimal number.\n", " %U | 36 | Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0.\n", " %c | Sun Sep 8 07:06:05 2013 | Locale’s appropriate date and time representation.\n", " %x | 09/08/13 | Locale’s appropriate date representation.\n", " %X | 07:06:05 | Locale’s appropriate time representation.\n", " %% | % |A literal '%' character." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# enter a second date interactively. Use the format 'mm/DD/YY'):\n", "day_string_2 = input('Enter MM/DD/YY')\n", "print(day_string_2)\n", "my_day_2 = dt.datetime.strptime(day_string_2,'%m/%d/%y')\n", "print(my_day_2) " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#once you have times as datetime objects, then you can make comparisons, etc.\n", "day_diff = my_day_2 - my_day_1\n", "print(day_diff)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# datetime.strftime() converts a datetime object to a string \n", "# this is really useful for labeling in plots\n", "#representing a date and time using a specific format string.\n", "#See Table 15.1 pg 215" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#print 4 digit year, month, day separately\n", "my_day_1_yr = dt.datetime.strftime(my_day_1,'%y')\n", "my_day_1_mn = dt.datetime.strftime(my_day_1,'%m')\n", "my_day_1_dy = dt.datetime.strftime(my_day_1,'%d')\n", "print(my_day_1_yr,my_day_1_mn,my_day_1_dy)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pandas handles time using the same conventions " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# take a list of times and use in pandas via the to_datetime function\n", "times = [ '09/08/13','07:06:05']\n", "print(type(times))\n", "time = pd.to_datetime(times, utc=True)\n", "print(type(time))\n", "#note how the missing time values are \"filled in\" by default\n", "time" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Here, it was specified that the times were in utc \n", "# Lets apply a time conversion that converts our times from UTC to MT\n", "time = time.tz_convert('US/Mountain')\n", "print(time)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Cautionary tale:** Working with time objects can be one of the more frustrating parts of programming as you work with figure labels. But Pandas helps a great deal to handle index times\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Check Your Understanding Chapter 15" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#here is a random date to use. it will be different each time" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from random import randint,random\n", "import datetime\n", "# we do a lot in UTC time. start with right now\n", "startdate = dt.datetime.utcnow()\n", "print(startdate)\n", "#random day within the past or future year\n", "date=startdate+datetime.timedelta(randint(-365,365))\n", "print(date)\n", "#add fraction of a day\n", "date=date+datetime.timedelta(random())\n", "print(date)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# 1) using strftime,print the date time object in the format Sun Sep 8 07:06:05 2013 \n", "# 2) what type of variable is the output?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#3) what is the julian date?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#4) use code to determine the current time, startdate, in east U.S. time zone" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#5) print out the time zone for the east US" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#6) For a code accessing day times throughout the year why is\n", "# it better NOT to define the timezone using the format of the output from #5?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#7) Use this resource (or another) to describe briefly the Y2K programming issue:\n", "#https://time.com/5752129/y2k-bug-history/" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 4 }