or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

easter.mdindex.mdparser.mdrelativedelta.mdrrule.mdtz.mdutils.mdzoneinfo.md

utils.mddocs/

0

# Date Utilities

1

2

General convenience functions for common date and time operations including current day calculation, timezone defaulting, and date comparison within tolerance.

3

4

## Capabilities

5

6

### Today Function

7

8

```python { .api }

9

def today(tzinfo=None):

10

"""

11

Return current date at midnight with optional timezone.

12

13

Parameters:

14

- tzinfo (tzinfo, optional): Timezone to attach and use for current day determination

15

16

Returns:

17

datetime: Current date at midnight (00:00:00) in specified timezone

18

"""

19

```

20

21

**Usage Examples:**

22

23

```python

24

from dateutil.utils import today

25

from dateutil.tz import gettz

26

from datetime import datetime

27

28

# Current day at midnight in local timezone

29

today_local = today()

30

print(f"Today (local): {today_local}")

31

32

# Current day at midnight in specific timezone

33

utc_tz = gettz('UTC')

34

today_utc = today(utc_tz)

35

print(f"Today (UTC): {today_utc}")

36

37

# Compare with datetime.now()

38

now = datetime.now(utc_tz)

39

today_utc_alt = today(utc_tz)

40

print(f"Now: {now}")

41

print(f"Today: {today_utc_alt}") # Same date, but time is 00:00:00

42

```

43

44

### Timezone Defaulting

45

46

```python { .api }

47

def default_tzinfo(dt, tzinfo):

48

"""

49

Set timezone on naive datetimes only, leaving aware datetimes unchanged.

50

51

Useful when dealing with datetimes that may have implicit or explicit timezones,

52

such as when parsing timezone strings or working with mixed timezone data.

53

54

Parameters:

55

- dt (datetime): Datetime object to potentially modify

56

- tzinfo (tzinfo): Timezone to assign if dt is naive

57

58

Returns:

59

datetime: Aware datetime (either original if already aware, or with tzinfo applied)

60

"""

61

```

62

63

**Usage Examples:**

64

65

```python

66

from dateutil.utils import default_tzinfo

67

from dateutil.tz import gettz

68

from dateutil.parser import parse

69

from datetime import datetime

70

71

eastern_tz = gettz('America/New_York')

72

73

# Apply timezone to naive datetime

74

naive_dt = datetime(2023, 12, 25, 14, 30)

75

aware_dt = default_tzinfo(naive_dt, eastern_tz)

76

print(f"Naive -> Aware: {aware_dt}")

77

78

# Aware datetime remains unchanged

79

already_aware = datetime(2023, 12, 25, 14, 30, tzinfo=gettz('UTC'))

80

still_aware = default_tzinfo(already_aware, eastern_tz)

81

print(f"Still UTC: {still_aware}") # Keeps original UTC timezone

82

83

# Practical example with parsing

84

def parse_with_default_tz(date_str, default_tz):

85

"""Parse date string and apply default timezone if none specified."""

86

parsed_dt = parse(date_str)

87

return default_tzinfo(parsed_dt, default_tz)

88

89

# Apply default timezone only when needed

90

dt1 = parse_with_default_tz("2023-12-25 14:30", eastern_tz) # Gets Eastern

91

dt2 = parse_with_default_tz("2023-12-25 14:30 UTC", eastern_tz) # Stays UTC

92

```

93

94

### Date Comparison with Tolerance

95

96

```python { .api }

97

def within_delta(dt1, dt2, delta):

98

"""

99

Check if two datetimes are within a specified tolerance of each other.

100

101

Useful for comparing datetimes that may have negligible differences

102

due to precision, network delays, or processing time.

103

104

Parameters:

105

- dt1 (datetime): First datetime

106

- dt2 (datetime): Second datetime

107

- delta (timedelta): Maximum allowed difference (tolerance)

108

109

Returns:

110

bool: True if absolute difference between dt1 and dt2 is <= delta

111

"""

112

```

113

114

**Usage Examples:**

115

116

```python

117

from dateutil.utils import within_delta

118

from datetime import datetime, timedelta

119

120

# Basic tolerance checking

121

dt1 = datetime(2023, 12, 25, 14, 30, 0, 0) # Exactly 14:30:00.000

122

dt2 = datetime(2023, 12, 25, 14, 30, 0, 500000) # 14:30:00.500 (500ms later)

123

124

tolerance = timedelta(seconds=1)

125

are_close = within_delta(dt1, dt2, tolerance)

126

print(f"Within 1 second: {are_close}") # True

127

128

# More strict tolerance

129

strict_tolerance = timedelta(milliseconds=100)

130

are_very_close = within_delta(dt1, dt2, strict_tolerance)

131

print(f"Within 100ms: {are_very_close}") # False

132

133

# Practical application: Event synchronization

134

def events_are_simultaneous(event1_time, event2_time, tolerance_seconds=5):

135

"""Check if two events occurred within tolerance of each other."""

136

tolerance = timedelta(seconds=tolerance_seconds)

137

return within_delta(event1_time, event2_time, tolerance)

138

139

# Example usage

140

event_a = datetime(2023, 12, 25, 14, 30, 15)

141

event_b = datetime(2023, 12, 25, 14, 30, 18)

142

143

simultaneous = events_are_simultaneous(event_a, event_b)

144

print(f"Events are simultaneous: {simultaneous}") # True (within 5 seconds)

145

```

146

147

## Advanced Usage Patterns

148

149

### Timezone-Aware Today Calculation

150

151

```python

152

from dateutil.utils import today

153

from dateutil.tz import gettz

154

from datetime import datetime

155

156

def business_day_start(timezone_name):

157

"""Get start of business day in specified timezone."""

158

tz = gettz(timezone_name)

159

return today(tz).replace(hour=9) # 9 AM start

160

161

def is_same_business_day(dt1, dt2, timezone_name):

162

"""Check if two datetimes fall on same business day."""

163

tz = gettz(timezone_name)

164

165

# Convert both to same timezone and compare dates

166

dt1_local = dt1.astimezone(tz) if dt1.tzinfo else dt1.replace(tzinfo=tz)

167

dt2_local = dt2.astimezone(tz) if dt2.tzinfo else dt2.replace(tzinfo=tz)

168

169

return dt1_local.date() == dt2_local.date()

170

171

# Example usage

172

ny_start = business_day_start('America/New_York')

173

london_start = business_day_start('Europe/London')

174

print(f"NY business day starts: {ny_start}")

175

print(f"London business day starts: {london_start}")

176

```

177

178

### Robust DateTime Processing Pipeline

179

180

```python

181

from dateutil.utils import default_tzinfo, within_delta

182

from dateutil.tz import gettz

183

from dateutil.parser import parse

184

from datetime import datetime, timedelta

185

186

class DateTimeProcessor:

187

"""Robust datetime processing with defaults and validation."""

188

189

def __init__(self, default_timezone='UTC', tolerance_seconds=1):

190

self.default_tz = gettz(default_timezone)

191

self.tolerance = timedelta(seconds=tolerance_seconds)

192

193

def normalize_datetime(self, dt_input):

194

"""Convert various datetime inputs to standardized format."""

195

if isinstance(dt_input, str):

196

dt = parse(dt_input)

197

else:

198

dt = dt_input

199

200

# Apply default timezone if naive

201

return default_tzinfo(dt, self.default_tz)

202

203

def are_equivalent(self, dt1, dt2):

204

"""Check if two datetime inputs represent equivalent times."""

205

norm_dt1 = self.normalize_datetime(dt1)

206

norm_dt2 = self.normalize_datetime(dt2)

207

208

return within_delta(norm_dt1, norm_dt2, self.tolerance)

209

210

# Usage example

211

processor = DateTimeProcessor('America/New_York', tolerance_seconds=5)

212

213

# Various input formats

214

inputs = [

215

"2023-12-25 14:30:00",

216

datetime(2023, 12, 25, 19, 30, 3, tzinfo=gettz('UTC')), # Same time in UTC

217

"Dec 25, 2023 2:30:02 PM EST"

218

]

219

220

# Normalize all inputs

221

normalized = [processor.normalize_datetime(inp) for inp in inputs]

222

for i, norm_dt in enumerate(normalized):

223

print(f"Input {i+1}: {norm_dt}")

224

225

# Check equivalence

226

print(f"All equivalent: {all(processor.are_equivalent(normalized[0], dt) for dt in normalized[1:])}")

227

```

228

229

### Data Quality Validation

230

231

```python

232

from dateutil.utils import within_delta

233

from datetime import datetime, timedelta

234

235

def validate_timestamp_sequence(timestamps, max_gap_minutes=60):

236

"""

237

Validate that timestamps form a reasonable sequence.

238

239

Parameters:

240

- timestamps: List of datetime objects

241

- max_gap_minutes: Maximum allowed gap between consecutive timestamps

242

243

Returns:

244

dict: Validation results with issues found

245

"""

246

issues = {

247

'out_of_order': [],

248

'large_gaps': [],

249

'duplicates': []

250

}

251

252

max_gap = timedelta(minutes=max_gap_minutes)

253

duplicate_tolerance = timedelta(seconds=1)

254

255

for i in range(len(timestamps) - 1):

256

current = timestamps[i]

257

next_ts = timestamps[i + 1]

258

259

# Check ordering

260

if current > next_ts:

261

issues['out_of_order'].append((i, i+1))

262

263

# Check for large gaps

264

gap = next_ts - current

265

if gap > max_gap:

266

issues['large_gaps'].append((i, i+1, gap))

267

268

# Check for duplicates (within tolerance)

269

if within_delta(current, next_ts, duplicate_tolerance):

270

issues['duplicates'].append((i, i+1))

271

272

return issues

273

274

# Example usage

275

test_timestamps = [

276

datetime(2023, 12, 25, 10, 0),

277

datetime(2023, 12, 25, 10, 15),

278

datetime(2023, 12, 25, 10, 15, 1), # Near duplicate

279

datetime(2023, 12, 25, 12, 0), # Large gap

280

datetime(2023, 12, 25, 11, 30), # Out of order

281

]

282

283

validation_results = validate_timestamp_sequence(test_timestamps)

284

print("Validation results:", validation_results)

285

```

286

287

## Types

288

289

```python { .api }

290

from datetime import datetime, timedelta, tzinfo

291

292

# Function signatures

293

def today(tzinfo: tzinfo | None = None) -> datetime: ...

294

def default_tzinfo(dt: datetime, tzinfo: tzinfo) -> datetime: ...

295

def within_delta(dt1: datetime, dt2: datetime, delta: timedelta) -> bool: ...

296

297

# Parameter types

298

DateTimeInput = datetime | str # For functions that accept multiple datetime formats

299

TimezoneInput = tzinfo | str | None # Timezone specifications

300

ToleranceInput = timedelta # Time tolerance specifications

301

```