@@ -18,7 +18,7 @@ package com.duckduckgo.app.attributed.metrics.store
1818
1919import  com.duckduckgo.di.scopes.AppScope 
2020import  com.squareup.anvil.annotations.ContributesBinding 
21- import  java.time.LocalDate  
21+ import  java.time.*  
2222import  java.time.format.DateTimeFormatter 
2323import  java.time.temporal.ChronoUnit 
2424import  javax.inject.Inject 
@@ -31,33 +31,41 @@ import javax.inject.Inject
3131 * - Calculating days between dates 
3232 * - Generating dates relative to the current date 
3333 * 
34-  * All dates are handled in the format "yyyy-MM-dd" for consistency across the feature. 
35-  * This format is used for both storage and calculations. 
34+  * All dates are handled in Eastern Time (ET) and formatted as "yyyy-MM-dd" for consistency. 
35+  * This format is used for both storage and calculations. The timezone ensures that day 
36+  * boundaries align with business operations in ET. 
3637 * 
3738 * Example usage: 
3839 * ``` 
39-  * // Get today's date 
40-  * val today = dateUtils.getCurrentDate() // returns "2025-10-03" 
40+  * // Get today's date in ET  
41+  * val today = dateUtils.getCurrentDate() // returns "2025-10-03" (if it's Oct 3rd in ET)  
4142 * 
42-  * // Get a date 7 days ago 
43+  * // Get a date 7 days ago in ET  
4344 * val lastWeek = dateUtils.getDateMinusDays(7) // returns "2025-09-26" 
4445 * 
45-  * // Calculate days since a specific date 
46+  * // Calculate days since a specific date in ET 
47+  * // Note: The calculation uses ET midnight as the boundary for day changes 
4648 * val daysSince = dateUtils.daysSince("2025-09-01") // returns number of days 
4749 * ``` 
50+  * 
51+  * Note: All date operations use Eastern Time (ET) timezone. This means: 
52+  * - Day changes occur at midnight ET 
53+  * - Date comparisons and calculations are based on ET dates 
54+  * - The returned date strings represent dates in ET 
4855 */  
4956interface  AttributedMetricsDateUtils  {
5057    /* *
51-      * Gets the current date formatted as "yyyy-MM-dd". 
58+      * Gets the current date in Eastern Time  formatted as "yyyy-MM-dd". 
5259     * 
53-      * @return The current date as a string in the format "yyyy-MM-dd" 
60+      * @return The current date in ET  as a string in the format "yyyy-MM-dd" 
5461     */  
5562    fun  getCurrentDate (): String 
5663
5764    /* *
58-      * Calculates the number of days between a given date and the current date. 
65+      * Calculates the number of days between a given date and the current date in Eastern Time. 
66+      * Day boundaries are determined using midnight ET. 
5967     * 
60-      * @param date The reference date in "yyyy-MM-dd" format 
68+      * @param date The reference date in "yyyy-MM-dd" format (interpreted in ET)  
6169     * @return The number of days between the reference date and current date. 
6270     *         Positive if the reference date is in the past, 
6371     *         negative if it's in the future, 
@@ -66,28 +74,35 @@ interface AttributedMetricsDateUtils {
6674    fun  daysSince (date :  String ): Int 
6775
6876    /* *
69-      * Gets a date that is a specified number of days before the current date. 
77+      * Gets a date that is a specified number of days before the current date in Eastern Time. 
78+      * Day boundaries are determined using midnight ET. 
7079     * 
7180     * @param days The number of days to subtract from the current date 
72-      * @return The calculated date as a string in "yyyy-MM-dd" format 
81+      * @return The calculated date as a string in "yyyy-MM-dd" format (in ET)  
7382     */  
7483    fun  getDateMinusDays (days :  Int ): String 
7584}
7685
7786@ContributesBinding(AppScope ::class )
7887class  RealAttributedMetricsDateUtils  @Inject constructor() : AttributedMetricsDateUtils {
79-     override  fun  getCurrentDate (): String  =  getCurrentLocalDate ().format(DATE_FORMATTER )
88+     override  fun  getCurrentDate (): String  =  getCurrentZonedDateTime ().format(DATE_FORMATTER )
8089
8190    override  fun  daysSince (date :  String ): Int  {
82-         val  initDate =  LocalDate .parse(date, DATE_FORMATTER )
83-         return  ChronoUnit .DAYS .between(initDate, getCurrentLocalDate()).toInt()
91+         //  Parse the input date and set it to start of day (midnight) in ET
92+         val  initDate =  ZonedDateTime .of(
93+             LocalDate .parse(date, DATE_FORMATTER ),
94+             LocalTime .MIDNIGHT ,
95+             ET_ZONE ,
96+         )
97+         return  ChronoUnit .DAYS .between(initDate, getCurrentZonedDateTime()).toInt()
8498    }
8599
86-     override  fun  getDateMinusDays (days :  Int ): String  =  getCurrentLocalDate ().minusDays(days.toLong()).format(DATE_FORMATTER )
100+     override  fun  getDateMinusDays (days :  Int ): String  =  getCurrentZonedDateTime ().minusDays(days.toLong()).format(DATE_FORMATTER )
87101
88-     private  fun  getCurrentLocalDate (): LocalDate  =  LocalDate .now()
102+     private  fun  getCurrentZonedDateTime (): ZonedDateTime  =  ZonedDateTime .now(ET_ZONE )
89103
90104    companion  object  {
91105        private  val  DATE_FORMATTER  =  DateTimeFormatter .ofPattern(" yyyy-MM-dd" 
106+         private  val  ET_ZONE  =  ZoneId .of(" America/New_York" 
92107    }
93108}
0 commit comments