Skip to content

Commit

Permalink
add massive test for converting from julian day
Browse files Browse the repository at this point in the history
  • Loading branch information
vcloarec committed Dec 12, 2019
1 parent cf25de4 commit c7279d0
Show file tree
Hide file tree
Showing 7 changed files with 9,959 additions and 30 deletions.
64 changes: 48 additions & 16 deletions mdal/mdal_datetime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ constexpr double MILLISECONDS_IN_WEEK = 1000 * 60 * 60 * 24 * 7;
constexpr double MILLISECONDS_IN_EXACT_YEAR = 3.15569259747e10; //CF Compliant
constexpr double MILLISECONDS_IN_MONTH_CF = MILLISECONDS_IN_EXACT_YEAR / 12; //CF Compliant

constexpr double SECONDS_IN_DAY = 60 * 60 * 24;
constexpr double MINUTES_IN_DAY = 60 * 24;
constexpr double HOURS_IN_DAY = 24;


MDAL::DateTime::DateTime(): mValid( false )
{}
Expand Down Expand Up @@ -54,15 +50,15 @@ MDAL::DateTime::DateTime( double value, Epoch epoch ):
mJulianTime = ( DateTime( 1970, 01, 01, 0, 0, 0, Gregorian ) + Duration( value, Duration::seconds ) ).mJulianTime;
break;
case MDAL::DateTime::JulianDay:
mJulianTime = int64_t( value * MILLISECONDS_IN_DAY );
mJulianTime = int64_t( value * MILLISECONDS_IN_DAY + 0.5 );
break;
}
}

std::string MDAL::DateTime::toStandartCalendarISO8601() const
{
DateTimeValues value = dateTimeGregorianJulianCalendar();
if ( mValid )
DateTimeValues value = dateTimeGregorianProleptic();
if ( mValid || value.year > 0 ) //Do not supoprt negative year
return toString( value );
else
return "";
Expand Down Expand Up @@ -168,8 +164,8 @@ MDAL::DateTime::DateTimeValues MDAL::DateTime::dateTimeGregorianJulianCalendar()
{
//https://fr.wikipedia.org/wiki/Jour_julien
DateTimeValues values;
int Z = int( mJulianTime / MILLISECONDS_IN_DAY + 0.5 ); //integer part of julian days count
double F = mJulianTime / MILLISECONDS_IN_DAY + 0.5 - Z; //fractional part of julian days count;
int Z = int( mJulianTime / MILLISECONDS_IN_DAY + 0.5 ); //integer part of julian days count
double F = ( mJulianTime - MILLISECONDS_IN_DAY * ( Z - 0.5 ) ) / MILLISECONDS_IN_DAY; //fractional part of julian days count;
int S;
if ( Z < 2299161 )
S = Z;
Expand All @@ -195,15 +191,51 @@ MDAL::DateTime::DateTimeValues MDAL::DateTime::dateTimeGregorianJulianCalendar()
else
values.year = C - 4715;

values.hours = int( F * HOURS_IN_DAY );
F = F - values.hours / HOURS_IN_DAY;
values.minutes = int( F * MINUTES_IN_DAY );
F = F - values.minutes / MINUTES_IN_DAY;
values.seconds = F * SECONDS_IN_DAY;
values.hours = int( F / MILLISECONDS_IN_HOUR );
F = int( F - values.hours * MILLISECONDS_IN_HOUR );
values.minutes = int( F / MILLISECONDS_IN_MINUTE );
F = int( F - values.minutes * MILLISECONDS_IN_MINUTE );
values.seconds = int( F / MILLISECONDS_IN_SECOND );

return values;
}

MDAL::DateTime::DateTimeValues MDAL::DateTime::dateTimeGregorianProleptic() const
{
//https://fr.wikipedia.org/wiki/Jour_julien
DateTimeValues values;
int Z = int( mJulianTime / MILLISECONDS_IN_DAY + 0.5 ); //integer part of julian days count
int F = int( mJulianTime - MILLISECONDS_IN_DAY * ( Z - 0.5 ) ) ; //fractional part of julian days count in ms;

int alpha = int( ( Z - 1867216.25 ) / 36524.25 );
int S = Z + 1 + alpha - int( alpha / 4 );

int B = S + 1524;
int C = int( ( B - 122.1 ) / 365.25 );
int D = int( 365.25 * C );
int E = int( ( B - D ) / 30.6001 );

values.day = B - D - int( 30.6001 * E );
if ( E < 14 )
values.month = E - 1;
else
values.month = E - 13;

if ( values.month > 2 )
values.year = C - 4716;
else
values.year = C - 4715;

values.hours = int( F / MILLISECONDS_IN_HOUR );
F = int( F - values.hours * MILLISECONDS_IN_HOUR );
values.minutes = int( F / MILLISECONDS_IN_MINUTE );
F = int( F - values.minutes * MILLISECONDS_IN_MINUTE );
values.seconds = int( F / MILLISECONDS_IN_SECOND );

return values;
}


void MDAL::DateTime::setWithGregorianCalendarDate( MDAL::DateTime::DateTimeValues values )
{
//https://quasar.as.utexas.edu/BillInfo/JulianDatesG.html
Expand Down Expand Up @@ -264,8 +296,6 @@ void MDAL::DateTime::setWithGregorianJulianCalendarDate( MDAL::DateTime::DateTim

std::string MDAL::DateTime::toString( MDAL::DateTime::DateTimeValues values ) const
{
std::string yearStr = std::to_string( values.year );

int miliseconds = int( ( values.seconds - int( values.seconds ) ) * 1000 + 0.5 );
std::string msStr;
if ( miliseconds > 0 )
Expand All @@ -274,6 +304,8 @@ std::string MDAL::DateTime::toString( MDAL::DateTime::DateTimeValues values ) co
msStr = prependZero( std::to_string( miliseconds ), 3 );
else if ( miliseconds < 100 )
msStr = prependZero( std::to_string( miliseconds ), 2 );
else if ( miliseconds < 1000 )
msStr = std::to_string( miliseconds );

msStr = std::string( "," ).append( msStr );
}
Expand Down
12 changes: 5 additions & 7 deletions mdal/mdal_datetime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
#ifndef MDAL_DATE_TIME_HPP
#define MDAL_DATE_TIME_HPP

// Macro for exporting symbols
// for unit tests (on windows)
#define MDAL_TEST_EXPORT MDAL_EXPORT

#include <string>
#include <vector>

Expand All @@ -18,7 +14,7 @@
namespace MDAL
{

class MDAL_TEST_EXPORT Duration
class Duration
{
public:
enum Unit
Expand Down Expand Up @@ -58,7 +54,7 @@ namespace MDAL
friend class DateTime;
};

class MDAL_TEST_EXPORT DateTime
class DateTime
{
public:

Expand All @@ -82,7 +78,8 @@ namespace MDAL
//! Constructor with Julian day
DateTime( double value, Epoch epoch );

//! Returns a string with the date/time expressed in Greogrian/Julian calendar with ISO8601 format (local time zone)
//! Returns a string with the date/time expressed in Greogrian proleptic calendar with ISO8601 format (local time zone)
//! Do not support negative year
std::string toStandartCalendarISO8601() const;

//! Returns the Julian day value
Expand Down Expand Up @@ -122,6 +119,7 @@ namespace MDAL
DateTime( int64_t julianTime );

DateTimeValues dateTimeGregorianJulianCalendar() const;
DateTimeValues dateTimeGregorianProleptic() const;

void setWithGregorianCalendarDate( DateTimeValues values );
void setWithJulianCalendarDate( DateTimeValues values );
Expand Down
4 changes: 2 additions & 2 deletions mdal/mdal_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,11 @@ namespace MDAL

//! parse the time unit in the CF convention string format "XXXX since 2019-01-01 00:00:00"
//! https://www.unidata.ucar.edu/software/netcdf-java/current/CDM/CalendarDateTime.html
Duration::Unit MDAL_TEST_EXPORT parseCFTimeUnit( std::string timeInformation );
Duration::Unit parseCFTimeUnit( std::string timeInformation );

//! parse the reference time in the CF convention string format "XXXX since 2019-01-01 00:00:00"
//! https://www.unidata.ucar.edu/software/netcdf-java/current/CDM/CalendarDateTime.html
MDAL::DateTime MDAL_TEST_EXPORT parseCFReferenceTime( const std::string &timeInformation, const std::string &calendarString );
MDAL::DateTime parseCFReferenceTime( const std::string &timeInformation, const std::string &calendarString );

} // namespace MDAL
#endif //MDAL_UTILS_HPP
Loading

0 comments on commit c7279d0

Please sign in to comment.