You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
386 lines
8.5 KiB
386 lines
8.5 KiB
/*****************************************************************************/
|
|
// Copyright 2006-2008 Adobe Systems Incorporated
|
|
// All Rights Reserved.
|
|
//
|
|
// NOTICE: Adobe permits you to use, modify, and distribute this file in
|
|
// accordance with the terms of the Adobe license agreement accompanying it.
|
|
/*****************************************************************************/
|
|
|
|
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_date_time.h#1 $ */
|
|
/* $DateTime: 2012/05/30 13:28:51 $ */
|
|
/* $Change: 832332 $ */
|
|
/* $Author: tknoll $ */
|
|
|
|
/** \file
|
|
* Functions and classes for working with dates and times in DNG files.
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
|
|
#ifndef __dng_date_time__
|
|
#define __dng_date_time__
|
|
|
|
/*****************************************************************************/
|
|
|
|
#include "dng_classes.h"
|
|
#include "dng_string.h"
|
|
#include "dng_types.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// \brief Class for holding a date/time and converting to and from relevant
|
|
/// date/time formats
|
|
|
|
class dng_date_time
|
|
{
|
|
|
|
public:
|
|
|
|
uint32 fYear;
|
|
uint32 fMonth;
|
|
uint32 fDay;
|
|
uint32 fHour;
|
|
uint32 fMinute;
|
|
uint32 fSecond;
|
|
|
|
public:
|
|
|
|
/// Construct an invalid date/time
|
|
|
|
dng_date_time ();
|
|
|
|
/// Construct a date/time with specific values.
|
|
/// \param year Year to use as actual integer value, such as 2006.
|
|
/// \param month Month to use from 1 - 12, where 1 is January.
|
|
/// \param day Day of month to use from 1 -31, where 1 is the first.
|
|
/// \param hour Hour of day to use from 0 - 23, where 0 is midnight.
|
|
/// \param minute Minute of hour to use from 0 - 59.
|
|
/// \param second Second of minute to use from 0 - 59.
|
|
|
|
dng_date_time (uint32 year,
|
|
uint32 month,
|
|
uint32 day,
|
|
uint32 hour,
|
|
uint32 minute,
|
|
uint32 second);
|
|
|
|
/// Predicate to determine if a date is valid.
|
|
/// \retval true if all fields are within range.
|
|
|
|
bool IsValid () const;
|
|
|
|
/// Predicate to determine if a date is invalid.
|
|
/// \retval true if any field is out of range.
|
|
|
|
bool NotValid () const
|
|
{
|
|
return !IsValid ();
|
|
}
|
|
|
|
/// Equal operator.
|
|
|
|
bool operator== (const dng_date_time &dt) const
|
|
{
|
|
return fYear == dt.fYear &&
|
|
fMonth == dt.fMonth &&
|
|
fDay == dt.fDay &&
|
|
fHour == dt.fHour &&
|
|
fMinute == dt.fMinute &&
|
|
fSecond == dt.fSecond;
|
|
}
|
|
|
|
// Not-equal operator.
|
|
|
|
bool operator!= (const dng_date_time &dt) const
|
|
{
|
|
return !(*this == dt);
|
|
}
|
|
|
|
/// Set date to an invalid value.
|
|
|
|
void Clear ();
|
|
|
|
/// Parse an EXIF format date string.
|
|
/// \param s Input date string to parse.
|
|
/// \retval true if date was parsed successfully and date is valid.
|
|
|
|
bool Parse (const char *s);
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// \brief Class for holding a time zone.
|
|
|
|
class dng_time_zone
|
|
{
|
|
|
|
private:
|
|
|
|
enum
|
|
{
|
|
|
|
kMaxOffsetHours = 15,
|
|
kMinOffsetHours = -kMaxOffsetHours,
|
|
|
|
kMaxOffsetMinutes = kMaxOffsetHours * 60,
|
|
kMinOffsetMinutes = kMinOffsetHours * 60,
|
|
|
|
kInvalidOffset = kMinOffsetMinutes - 1
|
|
|
|
};
|
|
|
|
// Offset from GMT in minutes. Positive numbers are
|
|
// ahead of GMT, negative number are behind GMT.
|
|
|
|
int32 fOffsetMinutes;
|
|
|
|
public:
|
|
|
|
dng_time_zone ()
|
|
: fOffsetMinutes (kInvalidOffset)
|
|
{
|
|
}
|
|
|
|
void Clear ()
|
|
{
|
|
fOffsetMinutes = kInvalidOffset;
|
|
}
|
|
|
|
void SetOffsetHours (int32 offset)
|
|
{
|
|
fOffsetMinutes = SafeInt32Mult(offset, 60);
|
|
}
|
|
|
|
void SetOffsetMinutes (int32 offset)
|
|
{
|
|
fOffsetMinutes = offset;
|
|
}
|
|
|
|
void SetOffsetSeconds (int32 offset)
|
|
{
|
|
fOffsetMinutes = (offset > 0) ? ((offset + 30) / 60)
|
|
: ((offset - 30) / 60);
|
|
}
|
|
|
|
bool IsValid () const
|
|
{
|
|
return fOffsetMinutes >= kMinOffsetMinutes &&
|
|
fOffsetMinutes <= kMaxOffsetMinutes;
|
|
}
|
|
|
|
bool NotValid () const
|
|
{
|
|
return !IsValid ();
|
|
}
|
|
|
|
int32 OffsetMinutes () const
|
|
{
|
|
return fOffsetMinutes;
|
|
}
|
|
|
|
bool IsExactHourOffset () const
|
|
{
|
|
return IsValid () && ((fOffsetMinutes % 60) == 0);
|
|
}
|
|
|
|
int32 ExactHourOffset () const
|
|
{
|
|
return fOffsetMinutes / 60;
|
|
}
|
|
|
|
dng_string Encode_ISO_8601 () const;
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// \brief Class for holding complete data/time/zone information.
|
|
|
|
class dng_date_time_info
|
|
{
|
|
|
|
private:
|
|
|
|
// Is only the date valid and not the time?
|
|
|
|
bool fDateOnly;
|
|
|
|
// Date and time.
|
|
|
|
dng_date_time fDateTime;
|
|
|
|
// Subseconds string (stored in a separate tag in EXIF).
|
|
|
|
dng_string fSubseconds;
|
|
|
|
// Time zone, if known.
|
|
|
|
dng_time_zone fTimeZone;
|
|
|
|
public:
|
|
|
|
dng_date_time_info ();
|
|
|
|
bool IsValid () const;
|
|
|
|
bool NotValid () const
|
|
{
|
|
return !IsValid ();
|
|
}
|
|
|
|
void Clear ()
|
|
{
|
|
*this = dng_date_time_info ();
|
|
}
|
|
|
|
const dng_date_time & DateTime () const
|
|
{
|
|
return fDateTime;
|
|
}
|
|
|
|
void SetDateTime (const dng_date_time &dt)
|
|
{
|
|
fDateOnly = false;
|
|
fDateTime = dt;
|
|
}
|
|
|
|
const dng_string & Subseconds () const
|
|
{
|
|
return fSubseconds;
|
|
}
|
|
|
|
void SetSubseconds (const dng_string &s)
|
|
{
|
|
fSubseconds = s;
|
|
}
|
|
|
|
const dng_time_zone & TimeZone () const
|
|
{
|
|
return fTimeZone;
|
|
}
|
|
|
|
void SetZone (const dng_time_zone &zone)
|
|
{
|
|
fTimeZone = zone;
|
|
}
|
|
|
|
void Decode_ISO_8601 (const char *s);
|
|
|
|
dng_string Encode_ISO_8601 () const;
|
|
|
|
void Decode_IPTC_Date (const char *s);
|
|
|
|
dng_string Encode_IPTC_Date () const;
|
|
|
|
void Decode_IPTC_Time (const char *s);
|
|
|
|
dng_string Encode_IPTC_Time () const;
|
|
|
|
private:
|
|
|
|
void SetDate (uint32 year,
|
|
uint32 month,
|
|
uint32 day);
|
|
|
|
void SetTime (uint32 hour,
|
|
uint32 minute,
|
|
uint32 second);
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// Get the current date/time and timezone.
|
|
/// \param info Receives current data/time/zone.
|
|
|
|
void CurrentDateTimeAndZone (dng_date_time_info &info);
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// Convert UNIX "seconds since Jan 1, 1970" time to a dng_date_time
|
|
|
|
void DecodeUnixTime (uint32 unixTime, dng_date_time &dt);
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// Return timezone of current location at a given date.
|
|
/// \param dt Date at which to compute timezone difference. (For example, used
|
|
/// to determine Daylight Savings, etc.)
|
|
/// \retval Time zone for date/time dt.
|
|
|
|
dng_time_zone LocalTimeZone (const dng_date_time &dt);
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// Tag to encode date represenation format
|
|
|
|
enum dng_date_time_format
|
|
{
|
|
dng_date_time_format_unknown = 0, /// Date format not known
|
|
dng_date_time_format_exif = 1, /// EXIF date string
|
|
dng_date_time_format_unix_little_endian = 2, /// 32-bit UNIX time as 4-byte little endian
|
|
dng_date_time_format_unix_big_endian = 3 /// 32-bit UNIX time as 4-byte big endian
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
/// \brief Store file offset from which date was read.
|
|
///
|
|
/// Used internally by Adobe to update date in original file.
|
|
/// \warning Use at your own risk.
|
|
|
|
class dng_date_time_storage_info
|
|
{
|
|
|
|
private:
|
|
|
|
uint64 fOffset;
|
|
|
|
dng_date_time_format fFormat;
|
|
|
|
public:
|
|
|
|
/// The default constructor initializes to an invalid state.
|
|
|
|
dng_date_time_storage_info ();
|
|
|
|
/// Construct with file offset and date format.
|
|
|
|
dng_date_time_storage_info (uint64 offset,
|
|
dng_date_time_format format);
|
|
|
|
/// Predicate to determine if an offset is valid.
|
|
/// \retval true if offset is valid.
|
|
|
|
bool IsValid () const;
|
|
|
|
// The accessors throw if the data is not valid.
|
|
|
|
/// Getter for offset in file.
|
|
/// \exception dng_exception with fErrorCode equal to dng_error_unknown
|
|
/// if offset is not valid.
|
|
|
|
uint64 Offset () const;
|
|
|
|
/// Get for format date was originally stored in file. Throws a
|
|
/// dng_error_unknown exception if offset is invalid.
|
|
/// \exception dng_exception with fErrorCode equal to dng_error_unknown
|
|
/// if offset is not valid.
|
|
|
|
dng_date_time_format Format () const;
|
|
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
|
|
// Kludge: Global boolean to turn on fake time zones in XMP for old software.
|
|
|
|
extern bool gDNGUseFakeTimeZonesInXMP;
|
|
|
|
/*****************************************************************************/
|
|
|
|
#endif
|
|
|
|
/*****************************************************************************/
|