Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1813,6 +1813,7 @@ src/inet/Makefile
src/inet/tests/Makefile
src/lib/Makefile
src/lib/support/Makefile
src/lib/support/tests/Makefile
src/platform/Makefile
tests/Makefile
])
Expand Down
3 changes: 3 additions & 0 deletions src/lib/support/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
include $(abs_top_nlbuild_autotools_dir)/automake/pre.am

SUBDIRS = \
tests \
$(NULL)

include SupportLayer.am
Expand All @@ -41,4 +42,6 @@ libSupportLayer_adir = $(includedir)/support

dist_libSupportLayer_a_HEADERS = $(CHIP_BUILD_SUPPORT_LAYER_HEADER_FILES)

$(RECURSIVE_TARGETS): $(lib_LIBRARIES)

include $(abs_top_nlbuild_autotools_dir)/automake/post.am
2 changes: 2 additions & 0 deletions src/lib/support/SupportLayer.am
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ CHIP_BUILD_SUPPORT_LAYER_SOURCE_FILES = \
@top_builddir@/src/lib/support/FibonacciUtils.cpp \
@top_builddir@/src/lib/support/logging/CHIPLogging.cpp \
@top_builddir@/src/lib/support/RandUtils.cpp \
@top_builddir@/src/lib/support/TimeUtils.cpp \
$(NULL)

CHIP_BUILD_SUPPORT_LAYER_HEADER_FILES = \
Expand All @@ -41,6 +42,7 @@ CHIP_BUILD_SUPPORT_LAYER_HEADER_FILES = \
@top_builddir@/src/lib/support/logging/CHIPLogging.h \
@top_builddir@/src/lib/support/Base64.h \
@top_builddir@/src/lib/support/RandUtils.h \
@top_builddir@/src/lib/support/TimeUtils.h \
$(NULL)

if CHIP_WITH_NLFAULTINJECTION
Expand Down
38 changes: 20 additions & 18 deletions src/lib/support/TimeUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@

namespace chip {

enum {
enum
{
// Number of days during the invariant part of the year (after the leap day).
kDaysFromMarch1ToDecember31 = 306,

Expand Down Expand Up @@ -132,7 +133,8 @@ uint8_t DaysInMonth(uint16_t year, uint8_t month)
uint8_t FirstWeekdayOfYear(uint16_t year)
{
// Compute the day of the week for the first day of the given year using Gauss' algorithm.
return (1 + 5 * ((year - 1) % kLeapYearInterval) + 4 * ((year - 1) % kYearsPerCentury) + 6 * ((year - 1) % kYearsPerCycle)) % kDaysPerWeek;
return (1 + 5 * ((year - 1) % kLeapYearInterval) + 4 * ((year - 1) % kYearsPerCentury) + 6 * ((year - 1) % kYearsPerCycle)) %
kDaysPerWeek;
}

/**
Expand All @@ -154,7 +156,7 @@ uint8_t FirstWeekdayOfYear(uint16_t year)
* [OUTPUT] Corresponding day-of-month in standard form (1=1st, 2=2nd, etc.).
*
*/
void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t& month, uint8_t& dayOfMonth)
void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t & month, uint8_t & dayOfMonth)
{
uint8_t daysToMarch1 = DaysToMarch1(year);

Expand Down Expand Up @@ -202,7 +204,7 @@ void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t& month
* [OUTPUT] Ordinal day of year, base 1 (1=January 1st, 2=January 2nd, etc.).
*
*/
void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t& dayOfYear)
void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t & dayOfYear)
{
// Convert month to a March-based month number (i.e. 0=March, 1=April, ...11=February).
month = month + (month > kFebruary ? -3 : 9);
Expand Down Expand Up @@ -246,7 +248,7 @@ void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth,
* This function makes no attempt to verify the correct range of any arguments other than year.
* Therefore callers must make sure the supplied values are valid prior to calling the function.
*/
bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t& daysSinceEpoch)
bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t & daysSinceEpoch)
{
// NOTE: This algorithm is based on the logic described in http://howardhinnant.github.io/date_algorithms.html.

Expand Down Expand Up @@ -276,7 +278,8 @@ bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMon
uint32_t yearOfCycle = year - (cycle * kYearsPerCycle);

// Compute the relative day within the cycle, accounting for leap-years.
uint32_t dayOfCycle = (yearOfCycle * kDaysPerStandardYear) + dayOfYear - (yearOfCycle / kYearsPerCentury) + (yearOfCycle / kLeapYearInterval);
uint32_t dayOfCycle =
(yearOfCycle * kDaysPerStandardYear) + dayOfYear - (yearOfCycle / kYearsPerCentury) + (yearOfCycle / kLeapYearInterval);

// Compute the total number of days since the start of the logical calendar (0000-03-01).
uint32_t daysSinceCalendarStart = (cycle * kDaysPerCycle) + dayOfCycle;
Expand Down Expand Up @@ -306,7 +309,7 @@ bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMon
* [OUTPUT] Day-of-month in standard form (1=1st, 2=2nd, etc.).
*
*/
void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t& year, uint8_t& month, uint8_t& dayOfMonth)
void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth)
{
// NOTE: This algorithm is based on the logic described in http://howardhinnant.github.io/date_algorithms.html.

Expand All @@ -320,10 +323,11 @@ void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t& year, uint8
uint32_t dayOfCycle = daysSinceEpoch - (cycle * kDaysPerCycle);

// Compute the relative year within the cycle, adjusting for leap-years.
uint16_t yearOfCycle = (dayOfCycle - dayOfCycle/1460 + dayOfCycle/36524 - dayOfCycle/146096) / kDaysPerStandardYear;
uint16_t yearOfCycle = (dayOfCycle - dayOfCycle / 1460 + dayOfCycle / 36524 - dayOfCycle / 146096) / kDaysPerStandardYear;

// Compute the relative day with the year.
uint16_t dayOfYear = dayOfCycle - (yearOfCycle * kDaysPerStandardYear + yearOfCycle/kLeapYearInterval - yearOfCycle/kYearsPerCentury);
uint16_t dayOfYear =
dayOfCycle - (yearOfCycle * kDaysPerStandardYear + yearOfCycle / kLeapYearInterval - yearOfCycle / kYearsPerCentury);

// Compute a March-based month number (i.e. 0=March...11=February) from the day of year.
month = MarchBasedDayOfYearToMonth(dayOfYear);
Expand Down Expand Up @@ -364,7 +368,7 @@ void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t& year, uint8
* @note
* Given date must be equal to or greater than 1970-01-01.
*/
void AdjustCalendarDate(uint16_t& year, uint8_t& month, uint8_t& dayOfMonth, int32_t relativeDays)
void AdjustCalendarDate(uint16_t & year, uint8_t & month, uint8_t & dayOfMonth, int32_t relativeDays)
{
uint32_t daysSinceEpoch;

Expand Down Expand Up @@ -414,9 +418,8 @@ void AdjustCalendarDate(uint16_t& year, uint8_t& month, uint8_t& dayOfMonth, int
* True if the date/time was converted successfully. False if the given year falls outside the
* representable range.
*/
bool CalendarTimeToSecondsSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth,
uint8_t hour, uint8_t minute, uint8_t second,
uint32_t& secondsSinceEpoch)
bool CalendarTimeToSecondsSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint8_t hour, uint8_t minute, uint8_t second,
uint32_t & secondsSinceEpoch)
{
uint32_t daysSinceEpoch;

Expand Down Expand Up @@ -472,20 +475,19 @@ bool CalendarTimeToSecondsSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOf
* @param second
* [OUTPUT] Second (0-59).
*/
void SecondsSinceEpochToCalendarTime(uint32_t secondsSinceEpoch,
uint16_t& year, uint8_t& month, uint8_t& dayOfMonth,
uint8_t& hour, uint8_t& minute, uint8_t& second)
void SecondsSinceEpochToCalendarTime(uint32_t secondsSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth,
uint8_t & hour, uint8_t & minute, uint8_t & second)
{
uint32_t daysSinceEpoch = secondsSinceEpoch / kSecondsPerDay;
uint32_t timeOfDay = secondsSinceEpoch - (daysSinceEpoch * kSecondsPerDay);
uint32_t timeOfDay = secondsSinceEpoch - (daysSinceEpoch * kSecondsPerDay);

DaysSinceEpochToCalendarDate(daysSinceEpoch, year, month, dayOfMonth);

hour = (uint8_t)(timeOfDay / kSecondsPerHour);
timeOfDay -= (hour * kSecondsPerHour);
minute = (uint8_t)(timeOfDay / kSecondsPerMinute);
timeOfDay -= (minute * kSecondsPerMinute);
second = (uint8_t)timeOfDay;
second = (uint8_t) timeOfDay;
}

} // namespace chip
69 changes: 35 additions & 34 deletions src/lib/support/TimeUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,51 +30,54 @@

namespace chip {

enum {
kYearsPerCentury = 100,
enum
{
kYearsPerCentury = 100,
kLeapYearInterval = 4,

kMonthsPerYear = 12,

kMaxDaysPerMonth = 31,

kDaysPerWeek = 7,
kDaysPerWeek = 7,
kDaysPerStandardYear = 365,
kDaysPerLeapYear = kDaysPerStandardYear + 1,
kDaysPerLeapYear = kDaysPerStandardYear + 1,

kHoursPerDay = 24,
kHoursPerDay = 24,
kHoursPerWeek = kDaysPerWeek * kHoursPerDay,

kMinutesPerHour = 60,
kMinutesPerDay = kHoursPerDay * kMinutesPerHour,
kMinutesPerDay = kHoursPerDay * kMinutesPerHour,

kSecondsPerMinute = 60,
kSecondsPerHour = kSecondsPerMinute * kMinutesPerHour,
kSecondsPerDay = kSecondsPerHour * kHoursPerDay,
kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek,
kSecondsPerMinute = 60,
kSecondsPerHour = kSecondsPerMinute * kMinutesPerHour,
kSecondsPerDay = kSecondsPerHour * kHoursPerDay,
kSecondsPerWeek = kSecondsPerDay * kDaysPerWeek,
kSecondsPerStandardYear = kSecondsPerDay * kDaysPerStandardYear,

kMillisecondPerSecond = 1000,

kMicrosecondsPerSecond = 1000000
};

enum {
kJanuary = 1,
kFebruary = 2,
kMarch = 3,
kApril = 4,
kMay = 5,
kJune = 6,
kJuly = 7,
kAugust = 8,
enum
{
kJanuary = 1,
kFebruary = 2,
kMarch = 3,
kApril = 4,
kMay = 5,
kJune = 6,
kJuly = 7,
kAugust = 8,
kSeptember = 9,
kOctober = 10,
kNovember = 11,
kDecember = 12
kOctober = 10,
kNovember = 11,
kDecember = 12
};

enum {
enum
{
// First year of the standard unix epoch.
kEpochYear = 1970,

Expand All @@ -88,17 +91,15 @@ enum {
extern bool IsLeapYear(uint16_t year);
extern uint8_t DaysInMonth(uint16_t year, uint8_t month);
extern uint8_t FirstWeekdayOfYear(uint16_t year);
extern void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t& month, uint8_t& dayOfMonth);
extern void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t& dayOfYear);
extern bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t& daysSinceEpoch);
extern void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t& year, uint8_t& month, uint8_t& dayOfMonth);
extern void AdjustCalendarDate(uint16_t& year, uint8_t& month, uint8_t& dayOfMonth, int32_t relativeDays);
extern bool CalendarTimeToSecondsSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth,
uint8_t hour, uint8_t minute, uint8_t second,
uint32_t& secondsSinceEpoch);
extern void SecondsSinceEpochToCalendarTime(uint32_t secondsSinceEpoch,
uint16_t& year, uint8_t& month, uint8_t& dayOfMonth,
uint8_t& hour, uint8_t& minute, uint8_t& second);
extern void OrdinalDateToCalendarDate(uint16_t year, uint16_t dayOfYear, uint8_t & month, uint8_t & dayOfMonth);
extern void CalendarDateToOrdinalDate(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint16_t & dayOfYear);
extern bool CalendarDateToDaysSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint32_t & daysSinceEpoch);
extern void DaysSinceEpochToCalendarDate(uint32_t daysSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth);
extern void AdjustCalendarDate(uint16_t & year, uint8_t & month, uint8_t & dayOfMonth, int32_t relativeDays);
extern bool CalendarTimeToSecondsSinceEpoch(uint16_t year, uint8_t month, uint8_t dayOfMonth, uint8_t hour, uint8_t minute,
uint8_t second, uint32_t & secondsSinceEpoch);
extern void SecondsSinceEpochToCalendarTime(uint32_t secondsSinceEpoch, uint16_t & year, uint8_t & month, uint8_t & dayOfMonth,
uint8_t & hour, uint8_t & minute, uint8_t & second);

/**
* @def secondsToMilliseconds
Expand Down
114 changes: 114 additions & 0 deletions src/lib/support/tests/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#
# Copyright (c) 2020 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

#
# Description:
# This file is the GNU automake template for the Project CHIP
# support layer library unit tests.
#

include $(abs_top_nlbuild_autotools_dir)/automake/pre.am

#
# Local headers to build against and distribute but not to install
# since they are not part of the package.
#
noinst_HEADERS = \
$(NULL)

#
# Other files we do want to distribute with the package.
#
EXTRA_DIST = \
$(NULL)

if CHIP_BUILD_TESTS
# C preprocessor option flags that will apply to all compiled objects in this
# makefile.

AM_CPPFLAGS = \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/lib \
$(LWIP_CPPFLAGS) \
$(SOCKETS_CPPFLAGS) \
$(PTHREAD_CFLAGS) \
$(NULL)

CHIP_LDADD = \
$(top_builddir)/src/lib/support/libSupportLayer.a \
$(NULL)

COMMON_LDADD = \
$(COMMON_LDFLAGS) \
$(CHIP_LDADD) \
$(LWIP_LDFLAGS) $(LWIP_LIBS) \
$(SOCKETS_LDFLAGS) $(SOCKETS_LIBS) \
$(PTHREAD_CFLAGS) $(PTHREAD_LIBS) \
$(NULL)

# Test applications that should be run when the 'check' target is run.

check_PROGRAMS = \
TestTimeUtils \
$(NULL)

# Test applications and scripts that should be built and run when the
# 'check' target is run.

TESTS = \
$(check_PROGRAMS) \
$(NULL)

# The additional environment variables and their values that will be
# made available to all programs and scripts in TESTS.

TESTS_ENVIRONMENT = \
$(NULL)

# Source, compiler, and linker options for test programs.

TestTimeUtils_SOURCES = TestTimeUtils.cpp
TestTimeUtils_LDADD = $(COMMON_LDADD)

if CHIP_BUILD_COVERAGE
CLEANFILES = $(wildcard *.gcda *.gcno)

if CHIP_BUILD_COVERAGE_REPORTS
# The bundle should positively be qualified with the absolute build
# path. Otherwise, VPATH will get auto-prefixed to it if there is
# already such a directory in the non-colocated source tree.

CHIP_COVERAGE_BUNDLE = ${abs_builddir}/${PACKAGE}${NL_COVERAGE_BUNDLE_SUFFIX}
CHIP_COVERAGE_INFO = ${CHIP_COVERAGE_BUNDLE}/${PACKAGE}${NL_COVERAGE_INFO_SUFFIX}

$(CHIP_COVERAGE_BUNDLE):
$(call create-directory)

$(CHIP_COVERAGE_INFO): check-local | $(CHIP_COVERAGE_BUNDLE)
$(call generate-coverage-report,${top_builddir})

coverage-local: $(CHIP_COVERAGE_INFO)

clean-local: clean-local-coverage

.PHONY: clean-local-coverage
clean-local-coverage:
-$(AM_V_at)rm -rf $(CHIP_COVERAGE_BUNDLE)
endif # CHIP_BUILD_COVERAGE_REPORTS
endif # CHIP_BUILD_COVERAGE
endif # CHIP_BUILD_TESTS

include $(abs_top_nlbuild_autotools_dir)/automake/post.am
Loading