mirror of
https://github.com/modrinth/code.git
synced 2026-09-02 13:05:50 +00:00
phoenix TZ
This commit is contained in:
@@ -54,18 +54,12 @@ async fn fetch_estimates(
|
|||||||
let first_period = periods_iter.next().wrap_err("no first period")?;
|
let first_period = periods_iter.next().wrap_err("no first period")?;
|
||||||
let last_period = periods_iter.last().unwrap_or(first_period);
|
let last_period = periods_iter.last().unwrap_or(first_period);
|
||||||
|
|
||||||
let range_start = first_period
|
let range_start = aditude::phoenix_midnight(first_period.date());
|
||||||
.date()
|
let range_end_date = last_period
|
||||||
.and_hms_opt(0, 0, 0)
|
|
||||||
.wrap_err("calculating payout period start")?
|
|
||||||
.and_utc();
|
|
||||||
let range_end = last_period
|
|
||||||
.date()
|
.date()
|
||||||
.checked_add_months(Months::new(1))
|
.checked_add_months(Months::new(1))
|
||||||
.wrap_err("calculating month after payout period end")?
|
.wrap_err("calculating month after payout period end")?;
|
||||||
.and_hms_opt(0, 0, 0)
|
let range_end = aditude::phoenix_midnight(range_end_date);
|
||||||
.wrap_err("calculating payout period end")?
|
|
||||||
.and_utc();
|
|
||||||
|
|
||||||
let metrics = aditude
|
let metrics = aditude
|
||||||
.get_metrics_v2(aditude::v2::GetMetrics {
|
.get_metrics_v2(aditude::v2::GetMetrics {
|
||||||
@@ -92,7 +86,7 @@ async fn fetch_estimates(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let date = row.time.date_naive();
|
let date = aditude::phoenix_date(row.time);
|
||||||
let period = YearMonth::from_day1(date);
|
let period = YearMonth::from_day1(date);
|
||||||
|
|
||||||
let period_estimate = map.entry(period).or_insert(PeriodEstimate {
|
let period_estimate = map.entry(period).or_insert(PeriodEstimate {
|
||||||
|
|||||||
@@ -8,9 +8,35 @@ pub mod v2;
|
|||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use chrono::{DateTime, Duration, Utc};
|
use chrono::{DateTime, Duration, FixedOffset, NaiveDate, Utc};
|
||||||
use secrecy::SecretString;
|
use secrecy::SecretString;
|
||||||
|
|
||||||
|
const PHOENIX_UTC_OFFSET_SECONDS: i32 = 7 * 60 * 60;
|
||||||
|
|
||||||
|
fn phoenix_offset() -> FixedOffset {
|
||||||
|
FixedOffset::west_opt(PHOENIX_UTC_OFFSET_SECONDS)
|
||||||
|
.expect("Phoenix UTC offset should be valid")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the UTC instant at which a calendar day starts in Phoenix.
|
||||||
|
///
|
||||||
|
/// Aditude buckets metrics in Phoenix time, which is MST (UTC-7) year-round.
|
||||||
|
#[must_use]
|
||||||
|
pub fn phoenix_midnight(date: NaiveDate) -> DateTime<Utc> {
|
||||||
|
date.and_hms_opt(0, 0, 0)
|
||||||
|
.expect("midnight should be valid")
|
||||||
|
.and_local_timezone(phoenix_offset())
|
||||||
|
.single()
|
||||||
|
.expect("a fixed offset should have one local midnight")
|
||||||
|
.with_timezone(&Utc)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the Phoenix calendar date containing a UTC instant.
|
||||||
|
#[must_use]
|
||||||
|
pub fn phoenix_date(time: DateTime<Utc>) -> NaiveDate {
|
||||||
|
time.with_timezone(&phoenix_offset()).date_naive()
|
||||||
|
}
|
||||||
|
|
||||||
/// [Aditude](https://www.aditude.com/) client.
|
/// [Aditude](https://www.aditude.com/) client.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
@@ -70,13 +96,7 @@ impl Client {
|
|||||||
/// range.
|
/// range.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn yesterday(now: DateTime<Utc>) -> (DateTime<Utc>, DateTime<Utc>) {
|
pub fn yesterday(now: DateTime<Utc>) -> (DateTime<Utc>, DateTime<Utc>) {
|
||||||
let start = DateTime::<Utc>::from_naive_utc_and_offset(
|
let start = phoenix_midnight(phoenix_date(now - Duration::days(1)));
|
||||||
(now - Duration::days(1))
|
|
||||||
.date_naive()
|
|
||||||
.and_hms_nano_opt(0, 0, 0, 0)
|
|
||||||
.unwrap_or_default(),
|
|
||||||
Utc,
|
|
||||||
);
|
|
||||||
let end = start + Duration::days(1);
|
let end = start + Duration::days(1);
|
||||||
(start, end)
|
(start, end)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#![expect(missing_docs, reason = "test crate")]
|
#![expect(missing_docs, reason = "test crate")]
|
||||||
|
|
||||||
use aditude::{Client, mock::AditudeMock, v1, v2};
|
use aditude::{Client, mock::AditudeMock, v1, v2};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, NaiveDate, TimeZone, Utc};
|
||||||
use rust_decimal::dec;
|
use rust_decimal::dec;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -115,3 +115,31 @@ async fn test_yesterday() {
|
|||||||
|
|
||||||
assert_eq!(real_yesterday, our_yesterday);
|
assert_eq!(real_yesterday, our_yesterday);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn phoenix_day_boundaries() {
|
||||||
|
let august_19 = NaiveDate::from_ymd_opt(2026, 8, 19).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
aditude::phoenix_midnight(august_19),
|
||||||
|
Utc.with_ymd_and_hms(2026, 8, 19, 7, 0, 0).unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let before_phoenix_midnight =
|
||||||
|
Utc.with_ymd_and_hms(2026, 8, 20, 6, 59, 59).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
aditude::yesterday(before_phoenix_midnight),
|
||||||
|
(
|
||||||
|
Utc.with_ymd_and_hms(2026, 8, 18, 7, 0, 0).unwrap(),
|
||||||
|
Utc.with_ymd_and_hms(2026, 8, 19, 7, 0, 0).unwrap(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
let phoenix_midnight = Utc.with_ymd_and_hms(2026, 8, 20, 7, 0, 0).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
aditude::yesterday(phoenix_midnight),
|
||||||
|
(
|
||||||
|
Utc.with_ymd_and_hms(2026, 8, 19, 7, 0, 0).unwrap(),
|
||||||
|
Utc.with_ymd_and_hms(2026, 8, 20, 7, 0, 0).unwrap(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user