Commit 87662384 authored by Gordon Ball's avatar Gordon Ball

New upstream version 1.1.0+ds.1

parent f22029ab
......@@ -5,6 +5,7 @@ contributions of the following people:
Federico Hernandez (Principal Author)
Dirk Deimeke (Technical Advisor)
Tomas Babej (Contributing Author)
Thomas Lauf (Contributing Author)
The following submitted code, packages or analysis, and deserve special thanks:
......@@ -18,6 +19,14 @@ The following submitted code, packages or analysis, and deserve special thanks:
Michael Meier
Martin Boeker
Felix Wolfsteller
Jörg Krause
Richard Brown
Armado Martinez
A M
asmyers
Lukas Barth
Paul J. Fenwick
Michael Neumann
Thanks to the following, who submitted detailed bug reports and excellent
suggestions:
......@@ -36,3 +45,16 @@ suggestions:
Michel Crucifix
Jonathon Bly
Felix Wolfsteller
hosaka
Aaron Evers
David Patrick
Georg Sauthoff
Josh Proehl
Mattia Rizzolo
m8r
Jan Stolarek
Yury Videneev
Plup
Bodo Graumann
Lynoure
Tim Ruffing
......@@ -6,7 +6,7 @@ set (HAVE_CMAKE true)
project (timew)
include (CXXSniffer)
set (PROJECT_VERSION "1.0.0")
set (PROJECT_VERSION "1.1.0")
message ("-- Looking for SHA1 references")
if (EXISTS ${CMAKE_SOURCE_DIR}/.git/index)
......@@ -27,13 +27,13 @@ set (PACKAGE_TARNAME "${PACKAGE}")
set (PACKAGE_VERSION "${VERSION}")
set (PACKAGE_STRING "${PACKAGE} ${VERSION}")
if (FREEBSD)
if (FREEBSD OR DRAGONFLY)
SET (TIMEW_MAN1DIR man/man1 CACHE STRING "Installation directory for man pages, section 1")
SET (TIMEW_MAN5DIR man/man5 CACHE STRING "Installation directory for man pages, section 5")
else (FREEBSD)
else (FREEBSD OR DRAGONFLY)
SET (TIMEW_MAN1DIR share/man/man1 CACHE STRING "Installation directory for man pages, section 1")
SET (TIMEW_MAN5DIR share/man/man5 CACHE STRING "Installation directory for man pages, section 5")
endif (FREEBSD)
endif (FREEBSD OR DRAGONFLY)
SET (TIMEW_DOCDIR share/doc/timew CACHE STRING "Installation directory for doc files")
message ("-- Configuring cmake.h")
......
......@@ -13,7 +13,7 @@ branch where your changes must go. If you see two branches, `1.2.3` and
Any patch against `master`, or an older development branch, means additional
merge work for maintainers, and will not be accepted. If your change is on the
wrong branch, rebase it onto the right branch. Then retest.
wrong branch, rebase it onto the right branch. Then retest before submitting.
By contributing a patch, you are declaring that you have the right to submit
the code under the project licensing terms.
......@@ -36,10 +36,6 @@ contribute that may not be immediately obvious to you:
suggestions, testing and discussions have taken place there. It is also
the quickest way to get help, or confirm a bug.
- Join https://answers.tasktools.org and help us by asking, answering and
voting on questions and answers, directly helping those who ask, and
helping future users who search for existing answers.
- Review documentation: there are man pages, online articles, tutorials and
so on, and these contain many errors, or they may not convey ideas in the
best way. Perhaps you can help improve it. Contact us - documentation is
......@@ -60,7 +56,7 @@ contribute that may not be immediately obvious to you:
the work is done well and doesn't create other problems or introduce new
dependencies. We recommend talking to us before starting. Seriously.
- Add unit tests. Unit tests are possibly the most useful contributions of
- Add unit tests. Unit tests are likely the most useful contributions of
all, because they not only improve the quality of the code, but prevent
future regressions, therefore maintaining quality of subsequent releases.
Plus, broken tests are a great motivator for us to fix the causal defect.
......@@ -92,7 +88,8 @@ How to make a patch
Clone the repository from the right place. Do not clone from our github mirror,
we don't use it. Do not patch the contents of one of our tarballs.
$ git clone https://git.tasktools.org/scm/tm/timew.git
$ git clone --recursive https://git.tasktools.org/TM/timew.git timew.git
$ cd timew.git
Find the latest development branch, and checkout.
......@@ -103,6 +100,8 @@ Find the latest development branch, and checkout.
remotes/origin/HEAD -> origin/master
remotes/origin/master
$ git checkout 1.2.4
$ git submodule init
$ git submodule update
Prepare your fix. Use a commit message that matches the prevailing format.
See 'git log' for examples.
......
Timewarrior - a command line time tracker
Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez.
Copyright 2015 - 2018, Paul Beckingham, Federico Hernandez.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......
1.1.0 (2018-01-13) -
- TD-120 Missing cmakedefine for HAVE_GET_CURRENT_DIR_NAME
(thanks to Jörg Krause, Ben Boeckel).
- TW-1845 Cygwin build fails, missing get_current_dir_name
(thanks to hosaka).
- TW-1936 Tweak tests to have fuller TAP compliance
(thanks to Paul J. Fenwick)
- TI-27 Continue tracking by ID
(thanks to Dennis Schubert)
- TI-29 timew config can't add new value
(thanks to Yury Vidineev)
- TI-32 taskwarrior hook script doesn't stop recording waiting task
(thanks to Yury Videneev).
- TI-39 Bogus command line option causes segfault
(thanks to Jan Stolarek, Thomas Lauf).
- TI-40 totals.py extension script fails with an error
(thanks to Jan Stolarek)
- TI-42 refresh holiday script throws an error on nb-NO locale
(thanks to Jelle van der Waa).
- TI-43 :lastweek on sunday
(thanks to Michel Crucifix).
- TI-46 Display error in visual reports (day,week,month)
(thanks to Michael Meier)
- TI-47 first call successfully creates new database but returns exit status 1
(thanks to Georg Sauthoff).
- TI-48 Timewarrior hook is not Python3 compatible
(thanks to Josh Proehl, Armado Martinez)
- TI-49 new theme files aren't installed
(thanks to Richard Brown).
- TI-51 in the taskwarrior hook, deleting a task doesn't stop the watch
(thanks to Mattia Rizzolo).
- TI-52 The 'refresh' scripts overwrites previous years data
(thanks to m8r).
- TI-58 Delete command is not always deleting
(thanks to Lynoure, asmyers).
- TI-61 Typo in exclusion.t.cpp
(thanks to Thomas Lauf).
- TI-62 TimeWarrior should not ignore invalid command
- TI-64 Command 'stop' with date before current interval's start date causes
segfault
(thanks to Thomas Lauf).
- TI-65 The 'tags' command should support a filter
- TI-66 Move with :adjust leaves overlapping intervals.
(thanks to A M)
- TI-67 Summary with parameters shows wrong ids
(thanks to Bodo Graumann)
- TI-68 Cannot shorten interval which has been moved into an exclusion.
(thanks to A M)
- TI-69 timew config converts integers to times
(thanks to Thomas Lauf).
- TI-70 Timew starts a new interval even if a current interval contains the
same set of tags
(thanks to Thomas Babej).
- TI-73 timew move with a specific time broken on 1.1.0
(thanks to A M).
- TI-75 The :fill hint not properly detecting the last interval
(thanks to Thomas Babej).
- TI-77 timew track seems to think today is tomorrow
(thanks to A M).
- TI-78 Tag parsing broken for tags starting with "or_"
(thanks to Lukas Barth).
- TI-81 Allow correction with filtered ids
(thanks to Plup)
- TI-85 :adjust creates overlapping interval
(thanks to Tim Ruffing)
- TI-90 Let 'continue' accept a date or a date range
- TI-91 Timewarrior does not compile on DragonFly
(thanks to Michael Neumann).
- Fixed Python 3 support of the holiday/refresh script
(thanks to Jelle van der Waa).
- Added missing man page link
(thanks to David Patrick).
- Taskwarrior projects are now used as-is as tags, and also split on the '.' to
represent project hierarchy as separate tags.
(thanks to Josh Proehl).
- New date names supported (see 'timew help date' or 'man timew').
- Named dates 'socw', 'socm', 'socq' and 'socy' are now named 'sow', 'som',
'soq' and 'soy'. Similarly the 'eocw' etc are modified. The 'c' is now
implicit.
------ current release ---------------------------
1.0.0 (2016-08-17) -
1.0.0 (2016-08-17) 6428ce89fcf2a5665d9351c50c2a84c98543206c
- WWW-12 yesterday tag not recognised
- WWW-12 yesterday tag not recognized
(thanks to Michel Crucifix).
- TI-34 Make timew more user-friendly by adding --help and default output
(thanks to Felix Wolfsteller).
......
......@@ -14,8 +14,8 @@ In order to build Timewarrior, you will need:
- make
You will need a C++ compiler that supports full C++11, which includes:
- gcc 4.7 (released 2012-03-23)
- clang 3.3 (released 2013-01-07)
- gcc 4.9 (released 2014-04-22)
- clang 3.4 (released 2014-01-02)
Basic Installation
......@@ -148,8 +148,7 @@ CMake with no reported problems, and the build will fail later. This is
almost always because CMake is mistaken about some assumption.
If a build does not succeed, please send the contents of the 'CMakeCache.txt'
and 'CMakeFiles/CMakeOutput.log' files to support@taskwarrior.org, or post a
message in the support forums at taskwarrior.org along with the information.
and 'CMakeFiles/CMakeOutput.log' files to support@taskwarrior.org.
If CMake runs but Timewarrior does not build, please send the contents of the
above files as well as a transcript from the build, which is not written to a
......
Timewarrior - a command line time tracker
Copyright 2015 - 2016, Paul Beckingham, Federico Hernandez.
Copyright 2015 - 2018, Paul Beckingham, Federico Hernandez.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......@@ -20,4 +20,4 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
http://www.opensource.org/licenses/mit-license.php
https://www.opensource.org/licenses/mit-license.php
New Features in 1.0.0
New Features in 1.1.0
- All features are new.
- Taskwarrior integration hook now uses a project 'Home.Garden' as a single
tag 'Home.Garden' as well as individual 'Home', 'Garden' tags.
- Taskwarrior integration hook now stops the clock in more situations, such
as deleting or waiting a task.
- The 'tags' command now supports filters.
- New date names supported (see 'timew help date' or 'man timew').
- Timewarrior and Taskwarrior now use the same date handling.
- The 'continue' command can resume tracking by @id.
- When specifying a time without a date (e.g. '10:00am'), the day is assumed
to be today, and is no longer projected back in time.
Features not implemented in 1.0.0
New Commands in 1.1.0
- The 'undo' command.
- The 'fill' command and ':adjust' hint are disabled for beta.
- Rules.
-
New Configuration Options 1.1.0
-
Newly Deprecated Features in 1.1.0
-
Removed Features in 1.1.0
- Named dates 'socw', 'socm', 'socq' and 'socy' are now named 'sow', 'som',
'soq' and 'soy'. Similarly the 'eocw' etc are modified. The 'c' is now
implicit.
Known Issues
......@@ -30,10 +51,6 @@ a bug, please enter a new issue at:
https://bug.tasktools.org
Or you can also report the issue in the forums at:
https://answers.tasktools.org
Or just send a message to:
support@taskwarrior.org
......
......@@ -2,7 +2,7 @@ Thank you for taking a look at Timewarrior!
Timewarrior is a time tracking utility that offers simple stopwatch features as
well as sophisticated calendar-base backfill, along with flexible reporting. It
is a portable, well supported and very active, Open Source project.
is a portable, well supported and very active Open Source project.
Although Timewarrior is a new project there is extensive online documentation.
You'll find all the details at:
......@@ -23,8 +23,7 @@ Please send your code patches to:
support@taskwarrior.org
Consider joining bug.tasktools.org, answers.tasktools.org and participating in
the future of Timewarrior.
Consider joining bug.tasktools.org and participating in the future of Timewarrior.
---
......
......@@ -28,9 +28,21 @@
#cmakedefine FREEBSD
#cmakedefine OPENBSD
#cmakedefine NETBSD
#cmakedefine DRAGONFLY
#cmakedefine HAIKU
#cmakedefine SOLARIS
#cmakedefine KFREEBSD
#cmakedefine GNUHURD
#cmakedefine UNKNOWN
/* Found tm.tm_gmtoff struct member */
#cmakedefine HAVE_TM_GMTOFF
/* Found st.st_birthtime struct member */
#cmakedefine HAVE_ST_BIRTHTIME
/* Functions */
#cmakedefine HAVE_GET_CURRENT_DIR_NAME
#cmakedefine HAVE_TIMEGM
#cmakedefine HAVE_UUID_UNPARSE_LOWER
......@@ -33,6 +33,8 @@ elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
set (OPENBSD true)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD")
set (NETBSD true)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "DragonFly")
set (DRAGONFLY true)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
set (SOLARIS true)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "GNU")
......
......@@ -14,6 +14,11 @@ If you need a specific locale region, do this:
$ ./refresh --locale de-CH --region Bern
If the locale is not supported by holidata.net, or there is no data (yet) for
the locale for this year and next year, you will see an error.
By default, the current and next year are updated. If the locale is not
supported by holidata.net, or there is no data (yet) for the locale for this
year and next year, you will see an error.
To specify a set of years to update, do this:
$ ./refresh --locale en-US --year 2015 2016 2017
# Holiday data provided by Holidata.net
# http://holidata.net/en-US/2016.json
# Generated 2016-05-18T09:03:49
# Holiday data provided by holidata.net
# Generated 2018-01-13T00:44:23
define holidays:
en-US:
2016_01_01 = New Year's Day
2016_01_18 = Birthday of Martin Luther King, Jr.
2016_02_15 = Washington's Birthday
2016_04_18 = Patriots' Day
2016_04_18 = Patriots' Day
2016_05_30 = Memorial Day
2016_07_04 = Independence Day
2016_09_05 = Labor Day
2016_10_10 = Columbus Day
2016_11_11 = Veterans Day
2016_11_24 = Thanksgiving Day
2016_12_25 = Christmas Day
2017_01_01 = New Year's Day
2017_01_02 = New Year's Day (observed)
2017_01_16 = Birthday of Martin Luther King, Jr.
2017_02_20 = Washington's Birthday
2017_04_17 = Patriots' Day
2017_04_17 = Patriots' Day
2017_05_29 = Memorial Day
2017_07_04 = Independence Day
2017_09_04 = Labor Day
2017_10_09 = Columbus Day
2017_11_11 = Veterans Day
2017_11_23 = Thanksgiving Day
2017_12_25 = Christmas Day
2018_01_01 = New Year's Day
2018_01_15 = Birthday of Martin Luther King, Jr.
2018_02_19 = Washington's Birthday
2018_04_16 = Patriots' Day
2018_04_16 = Patriots' Day
2018_05_28 = Memorial Day
2018_07_04 = Independence Day
2018_09_03 = Labor Day
2018_10_08 = Columbus Day
2018_11_11 = Veterans Day
2018_11_22 = Thanksgiving Day
2018_12_25 = Christmas Day
......@@ -25,8 +25,13 @@
##
################################################################################
import os, sys, re, time, datetime, json, argparse, urllib2
import os, sys, re, time, datetime, json, argparse
if sys.version_info >= (3,0):
from urllib.request import urlopen
from urllib.error import HTTPError
else:
from urllib2 import urlopen, HTTPError
def enumerate(path):
if not os.path.exists(path):
......@@ -42,44 +47,46 @@ def holidata(locale, year):
return "http://holidata.net/%s/%d.json" % (locale, year)
def update_locales(locales, regions):
update_single_year(locales, regions, datetime.datetime.now().year)
update_single_year(locales, regions, datetime.datetime.now().year + 1)
def update_locales(locales, regions, years):
if years == []:
years = [datetime.datetime.now().year, datetime.datetime.now().year + 1]
def update_single_year(locales, regions, year):
for locale in locales:
print holidata(locale, year)
try:
url = holidata(locale, year)
lines = urllib2.urlopen(url).read()
with open("holidays.%s" % locale, "w") as fh:
fh.write('# Holiday data provided by Holidata.net\n')
fh.write('# ' + url + '\n')
fh.write('# Generated ' + time.strftime('%Y-%m-%dT%H:%M:%S') + '\n\n')
fh.write('define holidays:\n')
fh.write(' ' + locale + ':\n')
for line in lines.split('\n'):
if line:
j = json.loads(line)
if j['region'] == '' or regions is None or len(regions) == 0 or j['region'] in regions:
day = j['date'].replace("-", "_")
desc = j['description']
fh.write(' %s = %s\n' % (day, desc))
except urllib2.HTTPError as e:
if e.code == 404:
print "Holidata.net does not have data for %s, for %d." % (locale, year)
else:
print e.code, e.read()
with open("holidays.%s" % locale, "w") as fh:
fh.write('# Holiday data provided by holidata.net\n')
fh.write('# Generated ' + time.strftime('%Y-%m-%dT%H:%M:%S') + '\n\n')
fh.write('define holidays:\n')
fh.write(' ' + locale + ':\n')
for year in years:
url = holidata(locale, year)
print(url)
try:
lines = urlopen(url).read().decode('utf-8')
for line in lines.split('\n'):
if line:
j = json.loads(line)
if j['region'] == '' or regions is None or len(regions) == 0 or j['region'] in regions:
day = j['date'].replace("-", "_")
desc = j['description']
data = ' %s = %s\n' % (day, desc)
if sys.version_info >= (3,0):
fh.write(data)
else:
fh.write(data.encode('utf-8'))
fh.write('\n')
except HTTPError as e:
if e.code == 404:
print("holidata.net does not have data for %s, for %d." % (locale, year))
else:
print(e.code, e.read())
def main(args):
if args.locale:
update_locales(args.locale, args.region)
update_locales(args.locale, args.region, args.year)
else:
# Enumerate all holiday files in the current directory.
locales = []
......@@ -90,7 +97,7 @@ def main(args):
# Extract the locale name.
locales.append(result.group(1))
update_locales(locales, args.region)
update_locales(locales, args.region, args.year)
if __name__ == "__main__":
......@@ -98,10 +105,11 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Update holiday data files. Simply run 'refresh' to update all of them.")
parser.add_argument('--locale', nargs='+', help='Specific locale to update.')
parser.add_argument('--region', nargs='+', help='Specific locale region to update.')
parser.add_argument('--year', nargs='+', help='Specific year to fetch.', type=int, default=[])
args = parser.parse_args()
try:
main(args)
except Exception as msg:
print 'Error:', msg
print('Error:', msg)
.TH timew 1 2016-08-17 "${PACKAGE_STRING}" "User Manuals"
.TH timew 1 2018-01-13 "${PACKAGE_STRING}" "User Manuals"
.SH NAME
timew \- A command line time tracker.
......@@ -61,13 +61,15 @@ See also 'hints', 'show'.
.TP
.B timew continue
Resumes tracking the most recently closed interval. For example:
Resumes tracking of closed intervals. For example:
$ timew track 9am - 10am tag1 tag2
$ timew continue
$ timew track 11am - 1pm tag3
$ timew continue @2
The 'continue' command creates a new interval, starting now, and using the
tags 'tag1' and 'tag2'.
Using the 'summary' command and specifying the ':ids' hint shows interval IDs.
This command is a convenient way to resume work without re-entering the
tags.
......@@ -125,7 +127,27 @@ Exports all the tracked time in JSON format. Supports filtering. For example:
.TP
.B timew extensions
Displays the directory containing the extension programs and a table showing
each extention and its status. See also 'diagnostics'.
each extension and its status. See also 'diagnostics'.
.TP
.B timew fill @<id> [@<id> ...]
The 'fill' command is used to adjust any interval to fill in surrounding gaps.
Using the 'summary' command, and specifying the ':ids' hint shows interval IDs.
Using the right ID, you can identify an interval to fill. For example, show
the IDs:
$ timew summary :week :ids
Then having selected '@2' as the interval you wish to fill:
$ timew fill @2
Note that you can fill multiple intervals:
$ timew fill @2 @10 @23
See also 'hints'.
.TP
.B timew gaps [<interval>] [<tag> ...]
......@@ -178,7 +200,7 @@ Then having selected '@1' and '@2' as the intervals you wish to join:
$ timew join @1 @2
See also 'split', 'lengthen', 'shorten'.
See also 'split', 'lengthen', 'shorten', 'resize'.
.TP
.B timew lengthen @<id> [@<id> ...] <duration>
......@@ -197,7 +219,7 @@ Note that you can lengthen multiple intervals,:
$ timew lengthen @2 @10 @23 1hour
See also 'summary', 'tag', 'untag', 'shorten'.
See also 'summary', 'tag', 'untag', 'shorten', 'resize'.
.TP
.B timew month [<interval>] [<tag> ...]
......@@ -233,7 +255,7 @@ Then having selected '@2' as the interval you wish to move:
$ timew move @2 9am
See also 'summary', 'tag', 'untag', 'lengthen', 'shorten'.
See also 'summary', 'tag', 'untag', 'lengthen', 'shorten', 'resize'.
.TP
.B timew [report] <report> [<interval>] [<tag> ...]
......@@ -246,6 +268,25 @@ are equivalent:
This does however assume there is a 'foo' extension installed.
.TP
.B timew resize @<id> [@<id> ...] <duration>
The 'resize' command is used to change the duration of a closed interval.
Using the 'summary' command, and specifying the ':ids' hint shows interval IDs.
Using the right ID, you can identify an interval to resize. For example, show
the IDs:
$ timew summary :week :ids
Then having selected '@3' as the interval you wish to resize:
$ timew resize @3 15mins
Note that you can resize multiple intervals,:
$ timew resize @3 @1 @13 1hour
See also 'summary', 'tag', 'untag', 'lengthen', 'shorten'.
.TP
.B timew shorten @<id> [@<id> ...] <duration>
The 'shorten' command is used to advance the end date of a closed interval.
......@@ -263,7 +304,7 @@ Note that you can shorten multiple intervals,:
$ timew shorten @2 @10 @23 1hour
See also 'summary', 'tag', 'untag', 'lengthen'.
See also 'summary', 'tag', 'untag', 'lengthen', 'resize'.
.TP
.B timew show
......@@ -352,8 +393,9 @@ Note that you can tag multiple intervals, with multiple tags:
See also 'summary', 'shorten', 'lengthen', 'untag'.
.TP
.B timew tags
Displays all the tags that have been used.
.B timew tags [<interval>] [<tag> ...]
Displays all the tags that have been used by default. When a filter is specified,
shows only the tags that were used during that time.
.TP
.B timew track <interval> [<tag> ...]
......@@ -468,6 +510,13 @@ Range hints provide convenient shortcuts to date ranges:
:lastmonth Last month
:lastquarter Last quarter
:lastyear Last year
:monday Previous monday
:tuesday Previous tuesday
:wednesday Previous wednesday
:thursday Previous thursday
:friday Previous friday
:saturday Previous saturday
:sunday Previous sunday
.SH DATES
Timewarrior supports the following date formats based on ISO-8601:
......@@ -513,7 +562,6 @@ In addition to the standard date formats, the following are supported:
now Current date and time
today Current date at 0:00:00
sod, eod Current date at 0:00:00 and 23:59:59
yesterday Yesterday at 0:00:00
tomorrow Tomorrow at 0:00:00 (midnight tonight)
<day-of-week> Previous named day at 0:00:00
......@@ -523,15 +571,24 @@ In addition to the standard date formats, the following are supported:
<epoch> POSIX time
later 2038-01-18T0:00:00 (Y2K38)
someday 2038-01-18T0:00:00 (Y2K38)
soy, eoy Previous start/end of year
socy, eocy Start/end of current year
soq, eoq Previous start/end of quarter
socq, eocq Start/end of current quarter
som, eom Previous start/end of month
socm, eocm Start/end of current month
sow, eow Previous start/end of week
socw, eocw Start/end of current week
sopd, eopd Start/end of previous day
sod, eod Start/end of current day
sond, eond Start/end of next day