phobos/std/gregorian.d
Jonathan M Davis d8488a9865 Phobos has now been changed to use std.datetime. Also, bug# 3848 has been fixed.
std.gregorian, std.date, and std.dateparse have all been marked as
scheduled for deprecation. Everywhere (except for std.file) which was
using std.date is now using std.datetime. std.file is now using
std.datetime but has a number of functions still using d_time but which
are marked as scheduled for deprecation. I tried to give as many as I
could pragmas indicating that they were scheduled for deprecation, but
at the moment, that requires that a function be a templated function, and
I couldn't templatize all of them. So, some functions in std.file are
only marked as scheduled for deprecation in their documentation and will
not give any warning on compilation.

I had to rename several functions in std.file in order to avoid making
any breaking changes. And since I was already having to mess with
function names, it seemed like a good time to change the names of a
number of the functions in std.file to use proper capitalization
(such as changing isdir to isDir) as has been discussed and overwhelmingly
supported in the newsgroup with regards to std.string. And since I was
making those changes, it seemed like a good time to fix bug# 3848
(functions in std.file don't take symbolic links into account) as well.
So, std.file should now deal with symlinks properly.

The issue which Andrei brought up with +VERSION causing the std.datetime
unit tests to fail on OSX has been fixed as well.
2011-01-19 11:10:18 +00:00

418 lines
9.8 KiB
D

// Written in the D programming language.
/**
$(RED Scheduled for deprecation. Please use std.datetime instead.)
Macros:
WIKI = Phobos/StdGregorian
Copyright: Copyright Andrei Alexandrescu 2008 - 2009.
License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
Authors: $(WEB erdani.org, Andrei Alexandrescu)
*/
/*
Copyright Andrei Alexandrescu 2010-.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
module std.gregorian;
pragma(msg, "std.gregorian has been scheduled for deprecation. "
"Please use std.datetime instead.");
version(posix) import core.sys.posix.time;
import std.typecons;
import std.conv;
version(unittest) import std.stdio;
version(none) unittest
{
auto d = Date(2010, May, 1);
auto d1 = d;
assert(d.year == 2010);
assert(d.month == May);
assert(d.day == 1);
assert(d.dayOfWeek == 6);
assert(d.dayOfYear == 121);
assert(Date(2010, Jan, 5).dayOfYear == 5);
}
version(none) unittest
{
auto d1 = Date(negInfin);
auto d2 = Date(posInfin);
auto d3 = Date(notADateTime);
auto d4 = Date(maxDateTime);
auto d5 = Date(minDateTime);
}
version(none) unittest
{
auto d1 = fromString("2002-1-25");
auto d2 = fromUndelimitedString("20020125");
}
version(none) unittest
{
auto d1 = dayClockLocalDay();
auto d2 = dayClockUniversalDay();
}
alias ushort GregYear;
alias ushort GregMonth;
alias ushort GregDay;
alias uint GregDayOfWeek;
alias uint GregDayOfYear;
enum { Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }
// Special constants
struct Special { ulong value; }
static immutable
notADateTime = Special(0),
negInfin = Special(1),
posInfin = Special(2),
minDateTime = Special(3),
maxDateTime = Special(4),
notSpecial = Special(5);
struct Date
{
this(uint year, uint month, uint day)
{
immutable
a = cast(ushort)((14-month)/12),
y = cast(ushort)(year + 4800 - a),
m = cast(ushort)(month + 12*a - 3);
days_ = day + ((153*m + 2)/5) + 365*y + (y/4)
- (y/100) + (y/400) - 32045;
}
this(Special s)
{
}
// Accessors
@property GregYear year() const
{
immutable
a = days_ + 32044,
b = (4*a + 3)/146097,
c = a-((146097*b)/4),
d = (4*c + 3)/1461,
e = c - (1461*d)/4,
m = (5*e + 2)/153;
//auto day = cast(ushort) (e - ((153*m + 2)/5) + 1);
//auto month = cast(ushort) (m + 3 - 12 * (m/10));
immutable year = cast(ushort) (100*b + d - 4800 + (m/10));
return year;
}
@property GregMonth month() const
{
immutable
a = days_ + 32044,
b = (4*a + 3)/146097,
c = a-((146097*b)/4),
d = (4*c + 3)/1461,
e = c - (1461*d)/4,
m = (5*e + 2)/153;
//auto day = cast(ushort) (e - ((153*m + 2)/5) + 1);
immutable month = cast(ushort) (m + 3 - 12 * (m/10));
//auto year = cast(ushort) (100*b + d - 4800 + (m/10));
return month;
}
@property GregDay day() const
{
immutable
a = days_ + 32044,
b = (4*a + 3)/146097,
c = a-((146097*b)/4),
d = (4*c + 3)/1461,
e = c - (1461*d)/4,
m = (5*e + 2)/153,
day = cast(ushort) (e - ((153*m + 2)/5) + 1);
//auto month = cast(ushort) (m + 3 - 12 * (m/10));
//auto year = cast(ushort) (100*b + d - 4800 + (m/10));
return day;
}
@property Tuple!(GregYear, GregMonth, GregDay)
yearMonthDay() const
{
immutable
a = days_ + 32044,
b = (4*a + 3)/146097,
c = a-((146097*b)/4),
d = (4*c + 3)/1461,
e = c - (1461*d)/4,
m = (5*e + 2)/153;
auto day = cast(ushort) (e - ((153*m + 2)/5) + 1);
auto month = cast(ushort) (m + 3 - 12 * (m/10));
auto year = cast(ushort) (100*b + d - 4800 + (m/10));
return tuple(year, month, day);
}
@property GregDayOfWeek dayOfWeek() const
{
immutable
ymd = yearMonthDay,
a = cast(ushort) ((14-ymd._1)/12),
y = cast(ushort) (ymd._0 - a),
m = cast(ushort) (ymd._1 + 12*a - 2),
d = cast(ushort) ((ymd._2 + y + (y/4) - (y/100) +
(y/400) + (31*m)/12) % 7);
return d;
}
@property GregDayOfYear dayOfYear() const
{
const start_of_year = Date(year(), 1, 1);
auto doy = cast(ushort) ((this - start_of_year).days() + 1);
return cast(GregDayOfYear) doy;
}
@property Date endOfMonth() const
{
assert(0);
}
@property bool isInfinity() const
{
return isNegInfinity || isPosInfinity;
}
@property bool isNegInfinity() const
{
return days_ == negInfin.value;
}
@property bool isPosInfinity() const
{
return days_ == posInfin.value;
}
@property bool isNotADate() const
{
return days_ == notADateTime.value;
}
@property bool isSpecial() const
{
return isNotADate || isInfinity;
}
@property Special asSpecial() const
{
return days_ < notSpecial.value
? Special(days_)
: notSpecial;
}
@property long modJulianDay() const
{
auto ymd = yearMonthDay();
return julianDay(ymd) - 2400001; //prerounded
}
static @property long julianDay(Tuple!(ushort, ushort, ushort) ymd)
{
immutable
a = cast(ushort) ((14-ymd._1)/12),
y = cast(ushort) (ymd._0 + 4800 - a),
m = cast(ushort) (ymd._1 + 12*a - 3),
d = ymd._2 + ((153*m + 2)/5) + 365*y + (y/4) - (y/100)
+ (y/400) - 32045;
return d;
}
static bool isLeapYear(uint year)
{
//divisible by 4, not if divisible by 100, but true if
//divisible by 400
return (!(year % 4)) && ((year % 100) || (!(year % 400)));
}
@property int weekNumber() const
{
auto
ymd = yearMonthDay,
julianbegin = julianDay(tuple(cast(ushort)ymd._0,
cast(ushort)1, cast(ushort)1)),
juliantoday = julianDay(ymd);
long day = (julianbegin + 3) % 7;
ulong week = (juliantoday + day - julianbegin + 4)/7;
if ((week >= 1) && (week <= 52))
{
return cast(int) week;
}
if ((week == 53))
{
if((day==6) ||(day == 5 && isLeapYear(ymd._0)))
{
return cast(int) week; //under these circumstances week == 53.
}
else
{
return 1; //monday - wednesday is in week 1 of next year
}
}
//if the week is not in current year recalculate using the
//previous year as the beginning year
else
if (week == 0)
{
julianbegin = julianDay(
tuple(cast(ushort) (ymd._0 - 1), cast(ushort) 1,
cast(ushort) 1));
juliantoday = julianDay(ymd);
day = (julianbegin + 3) % 7;
week = (juliantoday + day - julianbegin + 4)/7;
return cast(int) week;
}
return cast(int) week; //not reachable -- well except if day == 5 and
//is_leap_year != true
}
@property uint endOfMonthDay() const
{
switch (month) {
case 2:
if (isLeapYear(year)) {
return 29;
} else {
return 28;
};
case 4:
case 6:
case 9:
case 11:
return 30;
default:
return 31;
}
}
@property string toSimpleString() const
{
auto ymd = yearMonthDay;
return text(ymd._0, '-', ymd._1, '-', ymd._2);
}
@property string toIsoString() const
{
assert(0);
}
@property string toIsoExtendedString() const
{
assert(0);
}
bool opEquals(ref const Date rhs) const
{
return days_ == rhs.days_;
}
int opCmp(in Date rhs) const
{
return days_ < rhs.days_ ? -1 : days_ > rhs.days_ ? 1 : 0;
}
// Date opBinary(string op)(const Date d) const
// if (op == "-")
// {
// }
Days opBinary(string op)(const Date d) const
if (op == "-")
{
if (!isSpecial && !d.isSpecial)
{
return Days(days_ - d.days_);
}
else
{
assert(0);
}
}
static if (is(tm))
{
tm toTm()
{
assert(0);
}
}
private ulong days_;
}
struct Days
{
private long days_;
this(long d) { days_ = d; }
this(Special s) { }
@property long days() const { return days_; }
@property bool isNegative() const { return days_ < 0; }
@property static Days unit() { return Days(1); }
@property bool isSpecial()
{
assert(0);
}
bool opEquals(ref const Days rhs) const
{
return days_ == rhs.days_;
}
int opCmp(in Days rhs) const
{
return days_ < rhs.days_ ? -1 : days_ > rhs.days_ ? 1 : 0;
}
Days opBinary(string op)(Days d) const
if (op == "+" || op == "-")
{
}
}
Date fromString(in char[] s)
{
Date result;
return result;
}
Date fromUndelimitedString(in char[] s)
{
Date result;
return result;
}
Date dayClockLocalDay()
{
Date result;
return result;
}
Date dayClockUniversalDay()
{
Date result;
return result;
}
static if (is(tm))
{
Date dateFromTm(tm)
{
assert(0);
}
}