1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
use chrono::offset::{TimeZone, Utc};
use chrono::DateTime;
use std::ops::{Add, Sub};
use std::time::Duration;
use std::time::SystemTime;
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub struct ASN1Time(DateTime<Utc>);
impl ASN1Time {
#[inline]
pub(crate) fn from_datetime_utc(dt: DateTime<Utc>) -> Self {
ASN1Time(dt)
}
pub fn from_timestamp(secs: i64) -> Self {
ASN1Time(Utc.timestamp(secs, 0))
}
#[inline]
pub fn timestamp(&self) -> i64 {
self.0.timestamp()
}
#[inline]
pub fn now() -> Self {
ASN1Time(SystemTime::now().into())
}
#[inline]
pub fn to_rfc2822(&self) -> String {
self.0.to_rfc2822()
}
}
impl Add<Duration> for ASN1Time {
type Output = Option<ASN1Time>;
#[inline]
fn add(self, rhs: Duration) -> Option<ASN1Time> {
let secs = rhs.as_secs();
const MAX_U32: u64 = 4_294_967_295;
if secs > MAX_U32 {
return None;
}
let duration = chrono::Duration::seconds(secs as i64);
let dt = self.0.checked_add_signed(duration)?;
Some(ASN1Time(dt))
}
}
impl Sub<ASN1Time> for ASN1Time {
type Output = Option<Duration>;
#[inline]
fn sub(self, rhs: ASN1Time) -> Option<Duration> {
self.0.signed_duration_since(rhs.0).to_std().ok()
}
}