📄 datetime.cpp
字号:
//
// DateTime.cpp
//
// $Id: //poco/Main/Foundation/src/DateTime.cpp#5 $
//
// Copyright (c) 2004, Guenter Obiltschnig/Applied Informatics.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Redistributions in any form must be accompanied by information on
// how to obtain complete source code for this software and any
// accompanying software that uses this software. The source code
// must either be included in the distribution or be available for no
// more than the cost of distribution plus a nominal fee, and must be
// freely redistributable under reasonable conditions. For an
// executable file, complete source code means the source code for all
// modules it contains. It does not include source code for modules or
// files that typically accompany the major components of the operating
// system on which the executable file runs.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
#include "Foundation/DateTime.h"
#include <math.h>
Foundation_BEGIN
inline double DateTime::toJulianDay(Timestamp::UtcTimeVal utcTime)
{
double utcDays = double(utcTime)/864000000000.0;
return utcDays + 2299160.5; // first day of Gregorian reform (Oct 15 1582)
}
inline Timestamp::UtcTimeVal DateTime::toUtcTime(double julianDay)
{
return Timestamp::UtcTimeVal((julianDay - 2299160.5)*864000000000.0);
}
DateTime::DateTime()
{
Timestamp now;
_utcTime = now.utcTime();
_julianDay = toJulianDay(_utcTime);
computeGregorian();
}
DateTime::DateTime(const Timestamp& timestamp):
_utcTime(timestamp.utcTime()),
_julianDay(toJulianDay(_utcTime))
{
computeGregorian();
}
DateTime::DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond):
_year(year),
_month(month),
_day(day),
_hour(hour),
_minute(minute),
_second(second),
_millisecond(millisecond),
_microsecond(microsecond)
{
poco_assert (year >= 0 && year <= 9999);
poco_assert (month >= 1 && month <= 12);
poco_assert (day >= 1 && day <= daysOfMonth(year, month));
poco_assert (hour >= 0 && hour <= 23);
poco_assert (minute >= 0 && minute <= 59);
poco_assert (second >= 0 && second <= 59);
poco_assert (millisecond >= 0 && millisecond <= 999);
poco_assert (microsecond >= 0 && millisecond <= 999);
_julianDay = toJulianDay(year, month, day, hour, minute, second, millisecond, microsecond);
_utcTime = toUtcTime(_julianDay);
}
DateTime::DateTime(double julianDay):
_utcTime(toUtcTime(julianDay)),
_julianDay(julianDay)
{
computeGregorian();
}
DateTime::DateTime(const DateTime& dateTime):
_utcTime(dateTime._utcTime),
_julianDay(dateTime._julianDay),
_year(dateTime._year),
_month(dateTime._month),
_day(dateTime._day),
_hour(dateTime._hour),
_minute(dateTime._minute),
_second(dateTime._second),
_millisecond(dateTime._millisecond),
_microsecond(dateTime._microsecond)
{
}
DateTime::~DateTime()
{
}
DateTime& DateTime::operator = (const DateTime& dateTime)
{
if (&dateTime != this)
{
_utcTime = dateTime._utcTime;
_julianDay = dateTime._julianDay;
_year = dateTime._year;
_month = dateTime._month;
_day = dateTime._day;
_hour = dateTime._hour;
_minute = dateTime._minute;
_second = dateTime._second;
_millisecond = dateTime._millisecond;
_microsecond = dateTime._microsecond;
}
return *this;
}
DateTime& DateTime::operator = (const Timestamp& timestamp)
{
_utcTime = timestamp.utcTime();
_julianDay = toJulianDay(_utcTime);
computeGregorian();
return *this;
}
DateTime& DateTime::operator = (double julianDay)
{
_julianDay = julianDay;
_utcTime = toUtcTime(julianDay);
computeGregorian();
return *this;
}
DateTime& DateTime::assign(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
{
poco_assert (year >= 0 && year <= 9999);
poco_assert (month >= 1 && month <= 12);
poco_assert (day >= 1 && day <= daysOfMonth(year, month));
poco_assert (hour >= 0 && hour <= 23);
poco_assert (minute >= 0 && minute <= 59);
poco_assert (second >= 0 && second <= 59);
poco_assert (millisecond >= 0 && millisecond <= 999);
poco_assert (microsecond >= 0 && millisecond <= 999);
_julianDay = toJulianDay(year, month, day, hour, minute, second, millisecond, microsecond);
_utcTime = toUtcTime(_julianDay);
_year = year;
_month = month;
_day = day;
_hour = hour;
_minute = minute;
_second = second;
_millisecond = millisecond;
return *this;
}
int DateTime::dayOfWeek() const
{
return int((floor(_julianDay + 1.5))) % 7;
}
int DateTime::dayOfYear() const
{
int doy = 0;
for (int month = 1; month < _month; ++month)
doy += daysOfMonth(_year, month);
doy += _day;
return doy;
}
int DateTime::daysOfMonth(int year, int month)
{
poco_assert (month >= 1 && month <= 12);
static int daysOfMonthTable[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if (month == 2 && isLeapYear(year))
return 29;
else
return daysOfMonthTable[month];
}
int DateTime::week(int firstDayOfWeek) const
{
poco_assert (firstDayOfWeek >= 0 && firstDayOfWeek <= 6);
/// find the first firstDayOfWeek.
int baseDay = 1;
while (DateTime(_year, 1, baseDay).dayOfWeek() != firstDayOfWeek) ++baseDay;
int doy = dayOfYear();
int offs = baseDay <= 4 ? 0 : 1;
if (doy < baseDay)
return offs;
else
return (doy - baseDay)/7 + 1 + offs;
}
double DateTime::toJulianDay(int year, int month, int day, int hour, int minute, int second, int millisecond, int microsecond)
{
// lookup table for (153*month - 457)/5 - note that 3 <= month <= 14.
static int lookup[] = {-91, -60, -30, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337};
// day to double
double dday = double(day) + ((double((hour*60 + minute)*60 + second)*1000 + millisecond)*1000 + microsecond)/86400000000.0;
if (month < 3)
{
month += 12;
--year;
}
double dyear = double(year);
return dday + lookup[month] + 365*year + floor(dyear/4) - floor(dyear/100) + floor(dyear/400) + 1721118.5;
}
void DateTime::computeGregorian()
{
double z = floor(_julianDay - 1721118.5);
double r = _julianDay - 1721118.5 - z;
double g = z - 0.25;
double a = floor(g / 36524.25);
double b = a - floor(a/4);
_year = short(floor((b + g)/365.25));
double c = b + z - floor(365.25*_year);
_month = short(floor((5*c + 456)/153));
double dday = c - floor((153.0*_month - 457)/5) + r;
_day = short(dday);
if (_month > 12)
{
++_year;
_month -= 12;
}
r *= 24;
_hour = short(floor(r));
r -= floor(r);
r *= 60;
_minute = short(floor(r));
r -= floor(r);
r *= 60;
_second = short(floor(r));
r -= floor(r);
r *= 1000;
_millisecond = short(r + 0.5);
}
Foundation_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -