Commit 1af3ae03 authored by Hilko Bengen's avatar Hilko Bengen

New upstream version 20171228

parent 3b97f129
dfdatetime (20171129-1) unstable; urgency=low
dfdatetime (20171228-1) unstable; urgency=low
* Auto-generated
-- Log2Timeline <log2timeline-dev@googlegroups.com> Wed, 29 Nov 2017 20:50:12 +0100
\ No newline at end of file
-- Log2Timeline <log2timeline-dev@googlegroups.com> Thu, 28 Dec 2017 10:11:45 +0100
\ No newline at end of file
......@@ -5,4 +5,4 @@ dfDateTime, or Digital Forensics date and time, provides date and time
objects to preserve accuracy and precision.
"""
__version__ = '20171129'
__version__ = '20171228'
......@@ -37,7 +37,7 @@ class CocoaTime(interface.DateTimeValues):
self.precision = definitions.PRECISION_1_SECOND
self.timestamp = timestamp
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a Cocoa timestamp from a date and time string.
Args:
......@@ -87,6 +87,27 @@ class CocoaTime(interface.DateTimeValues):
remainder = int((timestamp % 1) * 10000000)
return int(timestamp), remainder
def CopyToDateTimeString(self):
"""Copies the Cocoa timestamp to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.######
"""
if self.timestamp is None:
return
number_of_days, hours, minutes, seconds = self._GetTimeValues(
int(self.timestamp))
year, month, day_of_month = self._GetDateValues(
number_of_days, 2001, 1, 1)
microseconds = int((self.timestamp % 1) * 1000000)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:06d}'.format(
year, month, day_of_month, hours, minutes, seconds, microseconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
# -*- coding: utf-8 -*-
"""Function decorators."""
from __future__ import unicode_literals
import warnings
def deprecated(function):
"""Decorator to mark functions or methods as deprecated."""
def IssueDeprecationWarning(*args, **kwargs):
"""Issue a deprecation warning."""
warnings.simplefilter('always', DeprecationWarning)
warnings.warn('Call to deprecated function: {0:s}.'.format(
function.__name__), category=DeprecationWarning, stacklevel=2)
warnings.simplefilter('default', DeprecationWarning)
return function(*args, **kwargs)
IssueDeprecationWarning.__name__ = function.__name__
IssueDeprecationWarning.__doc__ = function.__doc__
IssueDeprecationWarning.__dict__.update(function.__dict__)
return IssueDeprecationWarning
......@@ -45,7 +45,7 @@ class DelphiDateTime(interface.DateTimeValues):
self.precision = definitions.PRECISION_1_MILLISECOND
self.timestamp = timestamp
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a Delphi TDateTime timestamp from a string.
Args:
......@@ -99,6 +99,29 @@ class DelphiDateTime(interface.DateTimeValues):
remainder = int((timestamp % 1) * 10000000)
return int(timestamp), remainder
def CopyToDateTimeString(self):
"""Copies the Delphi TDateTime timestamp to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.######
"""
if self.timestamp is None:
return
number_of_seconds = self.timestamp * self._SECONDS_PER_DAY
number_of_days, hours, minutes, seconds = self._GetTimeValues(
int(number_of_seconds))
year, month, day_of_month = self._GetDateValues(
number_of_days, 1899, 12, 30)
microseconds = int((number_of_seconds % 1) * 1000000)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:06d}'.format(
year, month, day_of_month, hours, minutes, seconds, microseconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -30,7 +30,7 @@ class FakeTime(interface.DateTimeValues):
self._number_of_seconds = int(timestamp)
self.precision = definitions.PRECISION_1_MICROSECOND
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a fake timestamp from a date and time string.
Args:
......@@ -72,6 +72,31 @@ class FakeTime(interface.DateTimeValues):
return self._number_of_seconds, None
def CopyToDateTimeString(self):
"""Copies the fake timestamp to a date and time string.
Returns:
str: date and time value formatted as one of the following:
YYYY-MM-DD hh:mm:ss
YYYY-MM-DD hh:mm:ss.######
"""
if self._number_of_seconds is None:
return
number_of_days, hours, minutes, seconds = self._GetTimeValues(
self._number_of_seconds)
year, month, day_of_month = self._GetDateValues(
number_of_days, 1970, 1, 1)
if self._microseconds is None:
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'.format(
year, month, day_of_month, hours, minutes, seconds)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:06d}'.format(
year, month, day_of_month, hours, minutes, seconds,
self._microseconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -93,7 +93,7 @@ class FATDateTime(interface.DateTimeValues):
number_of_seconds += number_of_days * self._SECONDS_PER_DAY
return number_of_seconds
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a FAT date time from a date and time string.
Args:
......@@ -139,6 +139,25 @@ class FATDateTime(interface.DateTimeValues):
timestamp = self._number_of_seconds + self._FAT_DATE_TO_POSIX_BASE
return timestamp, None
def CopyToDateTimeString(self):
"""Copies the FAT date time to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss
"""
if self._number_of_seconds is None:
return
number_of_days, hours, minutes, seconds = self._GetTimeValues(
self._number_of_seconds)
year, month, day_of_month = self._GetDateValues(
number_of_days, 1980, 1, 1)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'.format(
year, month, day_of_month, hours, minutes, seconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -37,7 +37,7 @@ class Filetime(interface.DateTimeValues):
self.precision = definitions.PRECISION_100_NANOSECONDS
self.timestamp = timestamp
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a FILETIME timestamp from a date and time string.
Args:
......@@ -88,6 +88,26 @@ class Filetime(interface.DateTimeValues):
timestamp -= self._FILETIME_TO_POSIX_BASE
return timestamp, remainder
def CopyToDateTimeString(self):
"""Copies the FILETIME timestamp to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.#######
"""
if (self.timestamp is None or self.timestamp < 0 or
self.timestamp > self._UINT64_MAX):
return
timestamp, remainder = divmod(self.timestamp, 10000000)
number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
year, month, day_of_month = self._GetDateValues(
number_of_days, 1601, 1, 1)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:07d}'.format(
year, month, day_of_month, hours, minutes, seconds, remainder)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -34,7 +34,7 @@ class HFSTime(interface.DateTimeValues):
self.precision = definitions.PRECISION_1_SECOND
self.timestamp = timestamp
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a HFS timestamp from a date and time string.
Args:
......@@ -81,6 +81,26 @@ class HFSTime(interface.DateTimeValues):
timestamp = self.timestamp - self._HFS_TO_POSIX_BASE
return timestamp, 0
def CopyToDateTimeString(self):
"""Copies the HFS timestamp to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss
"""
if (self.timestamp is None or self.timestamp < 0 or
self.timestamp > self._UINT32_MAX):
return
number_of_days, hours, minutes, seconds = self._GetTimeValues(
self.timestamp)
year, month, day_of_month = self._GetDateValues(
number_of_days, 1904, 1, 1)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'.format(
year, month, day_of_month, hours, minutes, seconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -6,6 +6,8 @@ from __future__ import unicode_literals
import abc
import calendar
from dfdatetime import decorators
class DateTimeValues(object):
"""Defines the date time values interface.
......@@ -299,6 +301,121 @@ class DateTimeValues(object):
return hours, minutes, seconds, microseconds, time_zone_offset
def _GetDateValues(
self, number_of_days, epoch_year, epoch_month, epoch_day_of_month):
"""Determines date values.
Args:
number_of_days (int): number of days since epoch.
epoch_year (int): year that is the start of the epoch.
epoch_month (int): month that is the start of the epoch.
epoch_day_of_month (int): day of month that is the start of the epoch.
Return:
tuple[int, int, int]: year, month, day of month.
Raises:
ValueError: if the epoch year, month or day of month values are out
of bounds.
"""
if epoch_year < 0:
raise ValueError('Epoch year value out of bounds.')
if epoch_month not in range(1, 13):
raise ValueError('Epoch month value out of bounds.')
epoch_days_per_month = self._GetDaysPerMonth(epoch_year, epoch_month)
if epoch_day_of_month < 1 or epoch_day_of_month > epoch_days_per_month:
raise ValueError('Epoch day of month value out of bounds.')
before_epoch = number_of_days < 0
year = epoch_year
month = epoch_month
if before_epoch:
month -= 1
if month <= 0:
month = 12
year -= 1
number_of_days += epoch_day_of_month
if before_epoch:
number_of_days *= -1
# Align with the start of the year.
while month > 1:
days_per_month = self._GetDaysPerMonth(year, month)
if number_of_days < days_per_month:
break
if before_epoch:
month -= 1
else:
month += 1
if month > 12:
month = 1
year += 1
number_of_days -= days_per_month
# Align with the start of the next century.
_, remainder = divmod(year, 100)
for _ in range(remainder, 100):
days_in_year = self._GetNumberOfDaysInYear(year)
if number_of_days < days_in_year:
break
if before_epoch:
year -= 1
else:
year += 1
number_of_days -= days_in_year
days_in_century = self._GetNumberOfDaysInCentury(year)
while number_of_days > days_in_century:
if before_epoch:
year -= 100
else:
year += 100
number_of_days -= days_in_century
days_in_century = self._GetNumberOfDaysInCentury(year)
days_in_year = self._GetNumberOfDaysInYear(year)
while number_of_days > days_in_year:
if before_epoch:
year -= 1
else:
year += 1
number_of_days -= days_in_year
days_in_year = self._GetNumberOfDaysInYear(year)
days_per_month = self._GetDaysPerMonth(year, month)
while number_of_days > days_per_month:
if before_epoch:
month -= 1
else:
month += 1
if month <= 0:
month = 12
year -= 1
elif month > 12:
month = 1
year += 1
number_of_days -= days_per_month
days_per_month = self._GetDaysPerMonth(year, month)
if before_epoch:
days_per_month = self._GetDaysPerMonth(year, month)
number_of_days = days_per_month - number_of_days
return year, month, number_of_days
def _GetDayOfYear(self, year, month, day_of_month):
"""Retrieves the day of the year for a specific day of a month in a year.
......@@ -348,6 +465,27 @@ class DateTimeValues(object):
return days_per_month
def _GetNumberOfDaysInCentury(self, year):
"""Retrieves the number of days in a century.
Args:
year (int): year in the century e.g. 1970.
Returns:
int: number of (remaining) days in the century.
Raises:
ValueError: if the year value is out of bounds.
"""
if year < 0:
raise ValueError('Year value out of bounds.')
year, _ = divmod(year, 100)
if self._IsLeapYear(year):
return 36525
return 36524
def _GetNumberOfDaysInYear(self, year):
"""Retrieves the number of days in a specific year.
......@@ -407,6 +545,20 @@ class DateTimeValues(object):
return int(number_of_seconds)
def _GetTimeValues(self, number_of_seconds):
"""Determines time values.
Args:
number_of_seconds (int): number of seconds.
Return:
tuple[int, int, int, int]: days, hours, minutes, seconds.
"""
number_of_minutes, seconds = divmod(number_of_seconds, 60)
number_of_hours, minutes = divmod(number_of_minutes, 60)
number_of_days, hours = divmod(number_of_hours, 24)
return number_of_days, hours, minutes, seconds
def _IsLeapYear(self, year):
"""Determines if a year is a leap year.
......@@ -419,7 +571,7 @@ class DateTimeValues(object):
# pylint: disable=consider-using-ternary
return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
@abc.abstractmethod
@decorators.deprecated
def CopyFromString(self, time_string):
"""Copies a date time value from a date and time string.
......@@ -435,7 +587,26 @@ class DateTimeValues(object):
Raises:
ValueError: if the time string is invalid or not supported.
"""
self.CopyFromDateTimeString(time_string)
@abc.abstractmethod
def CopyFromDateTimeString(self, time_string):
"""Copies a date time value from a date and time string.
Args:
time_string (str): date and time value formatted as:
YYYY-MM-DD hh:mm:ss.######[+-]##:##
Where # are numeric digits ranging from 0 to 9 and the seconds
fraction can be either 3 or 6 digits. The time of day, seconds
fraction and time zone offset are optional. The default time zone
is UTC.
Raises:
ValueError: if the time string is invalid or not supported.
"""
@abc.abstractmethod
def CopyToStatTimeTuple(self):
"""Copies the date time value to a stat timestamp tuple.
......@@ -444,6 +615,15 @@ class DateTimeValues(object):
100 nano seconds or (None, None) on error.
"""
@abc.abstractmethod
def CopyToDateTimeString(self):
"""Copies the date time value to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.######
"""
# TODO: remove this method when there is no more need for it in plaso.
@abc.abstractmethod
def GetPlasoTimestamp(self):
......
......@@ -36,7 +36,7 @@ class JavaTime(interface.DateTimeValues):
self.precision = definitions.PRECISION_1_MILLISECOND
self.timestamp = timestamp
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a Java timestamp from a date and time string.
Args:
......@@ -82,6 +82,26 @@ class JavaTime(interface.DateTimeValues):
timestamp, milliseconds = divmod(self.timestamp, 1000)
return timestamp, milliseconds * 10000
def CopyToDateTimeString(self):
"""Copies the Java timestamp to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.###
"""
if (self.timestamp is None or self.timestamp < self._INT64_MIN or
self.timestamp > self._INT64_MAX):
return
timestamp, milliseconds = divmod(self.timestamp, 1000)
number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
year, month, day_of_month = self._GetDateValues(
number_of_days, 1970, 1, 1)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:03d}'.format(
year, month, day_of_month, hours, minutes, seconds, milliseconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -34,7 +34,7 @@ class PosixTime(interface.DateTimeValues):
self.precision = definitions.PRECISION_1_SECOND
self.timestamp = timestamp
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a POSIX timestamp from a date and time string.
Args:
......@@ -72,6 +72,25 @@ class PosixTime(interface.DateTimeValues):
return self.timestamp, None
def CopyToDateTimeString(self):
"""Copies the POSIX timestamp to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss
"""
if self.timestamp is None:
return
number_of_days, hours, minutes, seconds = self._GetTimeValues(
self.timestamp)
year, month, day_of_month = self._GetDateValues(
number_of_days, 1970, 1, 1)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'.format(
year, month, day_of_month, hours, minutes, seconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......@@ -106,7 +125,7 @@ class PosixTimeInMicroseconds(interface.DateTimeValues):
self.precision = definitions.PRECISION_1_MICROSECOND
self.timestamp = timestamp
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a POSIX timestamp from a date and time string.
Args:
......@@ -148,6 +167,25 @@ class PosixTimeInMicroseconds(interface.DateTimeValues):
timestamp, microseconds = divmod(self.timestamp, 1000000)
return timestamp, microseconds * 10
def CopyToDateTimeString(self):
"""Copies the POSIX timestamp to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.######
"""
if self.timestamp is None:
return
timestamp, microseconds = divmod(self.timestamp, 1000000)
number_of_days, hours, minutes, seconds = self._GetTimeValues(timestamp)
year, month, day_of_month = self._GetDateValues(
number_of_days, 1970, 1, 1)
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:06d}'.format(
year, month, day_of_month, hours, minutes, seconds, microseconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -122,7 +122,7 @@ class RFC2579DateTime(interface.DateTimeValues):
self.year, self.month, self.day_of_month, self.hours, self.minutes,
self.seconds)
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a RFC2579 date-time from a date and time string.
Args:
......@@ -177,6 +177,20 @@ class RFC2579DateTime(interface.DateTimeValues):
return self._number_of_seconds, self.deciseconds * 1000000
def CopyToDateTimeString(self):
"""Copies the RFC2579 date-time to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss
"""
if self._number_of_seconds is None:
return
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'.format(
self.year, self.month, self.day_of_month, self.hours, self.minutes,
self.seconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -30,7 +30,7 @@ class SemanticTime(interface.DateTimeValues):
super(SemanticTime, self).__init__()
self.string = string
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies semantic time from a date and time string.
Args:
......@@ -42,6 +42,14 @@ class SemanticTime(interface.DateTimeValues):
"""
self.string = time_string
def CopyToDateTimeString(self):
"""Copies the date time value to a date and time string.
Returns:
str: semantic representation of the time, such as: "Never", "Not set".
"""
return self.string
def CopyToStatTimeTuple(self):
"""Copies the semantic timestamp to a stat timestamp tuple.
......
......@@ -102,7 +102,7 @@ class Systemtime(interface.DateTimeValues):
self.year, self.month, self.day_of_month, self.hours, self.minutes,
self.seconds)
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies a SYSTEMTIME structure from a date and time string.
Args:
......@@ -159,6 +159,20 @@ class Systemtime(interface.DateTimeValues):
return self._number_of_seconds, self.milliseconds * 10000
def CopyToDateTimeString(self):
"""Copies the SYSTEMTIME structure to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.###
"""
if self._number_of_seconds is None:
return
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:03d}'.format(
self.year, self.month, self.day_of_month, self.hours, self.minutes,
self.seconds, self.milliseconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......
......@@ -274,7 +274,7 @@ class TimeElements(interface.DateTimeValues):
return hours, minutes, seconds, microseconds, time_zone_offset
def CopyFromString(self, time_string):
def CopyFromDateTimeString(self, time_string):
"""Copies time elements from a date and time string.
Args:
......@@ -382,6 +382,21 @@ class TimeElements(interface.DateTimeValues):
return None, None
return self._number_of_seconds, None
def CopyToDateTimeString(self):
"""Copies the time elements to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss
"""
if self._number_of_seconds is None:
return
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'.format(
self._time_elements_tuple[0], self._time_elements_tuple[1],
self._time_elements_tuple[2], self._time_elements_tuple[3],
self._time_elements_tuple[4], self._time_elements_tuple[5])
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......@@ -487,6 +502,22 @@ class TimeElementsInMilliseconds(TimeElements):
return self._number_of_seconds, self._milliseconds * 10000
def CopyToDateTimeString(self):
"""Copies the time elements to a date and time string.
Returns:
str: date and time value formatted as:
YYYY-MM-DD hh:mm:ss.###
"""
if self._number_of_seconds is None or self._milliseconds is None:
return
return '{0:04d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:03d}'.format(
self._time_elements_tuple[0], self._time_elements_tuple[1],
self._time_elements_tuple[2], self._time_elements_tuple[3],
self._time_elements_tuple[4], self._time_elements_tuple[5],
self._milliseconds)
def GetPlasoTimestamp(self):
"""Retrieves a timestamp that is compatible with plaso.
......@@ -592,6 +623,22 @@ class TimeElementsInMicroseconds(TimeElements):