154359Sroberto/*
254359Sroberto * calyearstart - determine the NTP time at midnight of January 1 in
354359Sroberto *		  the year of the given date.
454359Sroberto */
5290001Sglebius#include <config.h>
654359Sroberto#include <sys/types.h>
754359Sroberto
854359Sroberto#include "ntp_types.h"
954359Sroberto#include "ntp_calendar.h"
1054359Sroberto#include "ntp_stdlib.h"
11290001Sglebius#include "ntp_assert.h"
1254359Sroberto
13290001Sglebius/*
14290001Sglebius * Juergen Perlinger, 2010-05-02
15290001Sglebius *
16290001Sglebius * Redone in terms of the calendar functions. It's rather simple:
17290001Sglebius * - expand the NTP time stamp
18290001Sglebius * - split into days and seconds since midnight, dropping the partial day
19290001Sglebius * - get full number of days before year start in NTP epoch
20290001Sglebius * - convert to seconds, truncated to 32 bits.
21290001Sglebius */
22290001Sglebiusu_int32
23290001Sglebiuscalyearstart(u_int32 ntptime, const time_t *pivot)
2454359Sroberto{
25290001Sglebius	u_int32      ndays; /* elapsed days since NTP starts */
26290001Sglebius	vint64       vlong;
27290001Sglebius	ntpcal_split split;
2854359Sroberto
29290001Sglebius	vlong = ntpcal_ntp_to_ntp(ntptime, pivot);
30290001Sglebius	split = ntpcal_daysplit(&vlong);
31290001Sglebius	ndays = ntpcal_rd_to_ystart(split.hi + DAY_NTP_STARTS)
32290001Sglebius	      - DAY_NTP_STARTS;
33290001Sglebius
34290001Sglebius	return (u_int32)(ndays * SECSPERDAY);
3554359Sroberto}
36290001Sglebius
37290001Sglebius/*
38290001Sglebius * calmonthstart - get NTP time at midnight of the first day of the
39290001Sglebius * current month.
40290001Sglebius */
41290001Sglebiusu_int32
42290001Sglebiuscalmonthstart(u_int32 ntptime, const time_t *pivot)
43290001Sglebius{
44290001Sglebius	u_int32      ndays; /* elapsed days since NTP starts */
45290001Sglebius	vint64       vlong;
46290001Sglebius	ntpcal_split split;
47290001Sglebius
48290001Sglebius	vlong = ntpcal_ntp_to_ntp(ntptime, pivot);
49290001Sglebius	split = ntpcal_daysplit(&vlong);
50290001Sglebius	ndays = ntpcal_rd_to_mstart(split.hi + DAY_NTP_STARTS)
51290001Sglebius	      - DAY_NTP_STARTS;
52290001Sglebius
53290001Sglebius	return (u_int32)(ndays * SECSPERDAY);
54290001Sglebius}
55290001Sglebius
56290001Sglebius/*
57290001Sglebius * calweekstart - get NTP time at midnight of the last monday on or
58290001Sglebius * before the current date.
59290001Sglebius */
60290001Sglebiusu_int32
61290001Sglebiuscalweekstart(u_int32 ntptime, const time_t *pivot)
62290001Sglebius{
63290001Sglebius	u_int32      ndays; /* elapsed days since NTP starts */
64290001Sglebius	vint64       vlong;
65290001Sglebius	ntpcal_split split;
66290001Sglebius
67290001Sglebius	vlong = ntpcal_ntp_to_ntp(ntptime, pivot);
68290001Sglebius	split = ntpcal_daysplit(&vlong);
69290001Sglebius	ndays = ntpcal_weekday_le(split.hi + DAY_NTP_STARTS, CAL_MONDAY)
70290001Sglebius	      - DAY_NTP_STARTS;
71290001Sglebius
72290001Sglebius	return (u_int32)(ndays * SECSPERDAY);
73290001Sglebius}
74290001Sglebius
75290001Sglebius/*
76290001Sglebius * caldaystart - get NTP time at midnight of the current day.
77290001Sglebius */
78290001Sglebiusu_int32
79290001Sglebiuscaldaystart(u_int32 ntptime, const time_t *pivot)
80290001Sglebius{
81290001Sglebius	vint64       vlong;
82290001Sglebius	ntpcal_split split;
83290001Sglebius
84290001Sglebius	vlong = ntpcal_ntp_to_ntp(ntptime, pivot);
85290001Sglebius	split = ntpcal_daysplit(&vlong);
86290001Sglebius
87290001Sglebius	return ntptime - split.lo;
88290001Sglebius}
89