mirror of
https://github.com/dlang/phobos.git
synced 2025-05-07 19:49:36 +03:00

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.
418 lines
9.8 KiB
D
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);
|
|
}
|
|
}
|