0
# Time Handling
1
2
Time representation and manipulation through the SubRipTime class. Supports the standard SubRip time format (HH:MM:SS,mmm), arithmetic operations, format conversion, and coercion from various input types.
3
4
## Capabilities
5
6
### Time Creation
7
8
Create time objects from various sources and formats.
9
10
```python { .api }
11
class SubRipTime:
12
def __init__(self, hours=0, minutes=0, seconds=0, milliseconds=0):
13
"""
14
Create a new SubRipTime instance.
15
16
Args:
17
hours (int): Hour component (default: 0)
18
minutes (int): Minute component (default: 0)
19
seconds (int): Second component (default: 0)
20
milliseconds (int): Millisecond component (default: 0)
21
"""
22
23
@classmethod
24
def coerce(cls, other):
25
"""
26
Convert various types to SubRipTime instance.
27
28
Args:
29
other: Input to convert (str, int, datetime.time, dict, tuple, or SubRipTime)
30
31
Returns:
32
SubRipTime: Converted time object
33
34
Supported types:
35
- str/unicode: "HH:MM:SS,mmm" format
36
- int: Total milliseconds
37
- datetime.time: Standard time object
38
- dict: {'hours': h, 'minutes': m, 'seconds': s, 'milliseconds': ms}
39
- tuple/list: (hours, minutes, seconds, milliseconds)
40
"""
41
42
@classmethod
43
def from_string(cls, source):
44
"""
45
Parse time from SubRip format string.
46
47
Args:
48
source (str): Time string in "HH:MM:SS,mmm" format
49
50
Returns:
51
SubRipTime: Parsed time object
52
53
Raises:
54
InvalidTimeString: If format is invalid
55
"""
56
57
@classmethod
58
def from_ordinal(cls, ordinal):
59
"""
60
Create time from total millisecond count.
61
62
Args:
63
ordinal (int): Total milliseconds
64
65
Returns:
66
SubRipTime: Time object representing the duration
67
"""
68
69
@classmethod
70
def from_time(cls, source):
71
"""
72
Create time from datetime.time object.
73
74
Args:
75
source (datetime.time): Standard time object
76
77
Returns:
78
SubRipTime: Converted time object
79
"""
80
81
@classmethod
82
def parse_int(cls, digits):
83
"""
84
Parse integer from string with error tolerance.
85
86
Args:
87
digits (str): String containing digits
88
89
Returns:
90
int: Parsed integer value (0 if parsing fails)
91
"""
92
```
93
94
### Time Components
95
96
Access and modify individual time components.
97
98
```python { .api }
99
@property
100
def hours(self):
101
"""
102
Hour component (0-23).
103
104
Returns:
105
int: Hours
106
"""
107
108
@property
109
def minutes(self):
110
"""
111
Minute component (0-59).
112
113
Returns:
114
int: Minutes
115
"""
116
117
@property
118
def seconds(self):
119
"""
120
Second component (0-59).
121
122
Returns:
123
int: Seconds
124
"""
125
126
@property
127
def milliseconds(self):
128
"""
129
Millisecond component (0-999).
130
131
Returns:
132
int: Milliseconds
133
"""
134
135
@property
136
def ordinal(self):
137
"""
138
Total time in milliseconds.
139
140
Returns:
141
int: Total milliseconds since 00:00:00,000
142
"""
143
```
144
145
### Time Operations
146
147
Perform arithmetic and timing operations.
148
149
```python { .api }
150
def shift(self, *args, **kwargs):
151
"""
152
Add time offset or apply ratio transformation.
153
154
Args:
155
*args: Positional time arguments (hours, minutes, seconds, milliseconds)
156
**kwargs: Named time arguments or ratio for scaling
157
158
Supported kwargs:
159
hours (int): Hours to add
160
minutes (int): Minutes to add
161
seconds (int): Seconds to add
162
milliseconds (int): Milliseconds to add
163
ratio (float): Multiply time by this ratio
164
"""
165
166
def to_time(self):
167
"""
168
Convert to standard datetime.time object.
169
170
Returns:
171
datetime.time: Standard Python time object
172
"""
173
```
174
175
### Arithmetic Operations
176
177
SubRipTime supports arithmetic operations with other time objects.
178
179
```python { .api }
180
# Addition
181
time1 + time2 # Add two times
182
time += other_time # In-place addition
183
184
# Subtraction
185
time1 - time2 # Subtract times
186
time -= other_time # In-place subtraction
187
188
# Multiplication (scaling)
189
time * ratio # Scale time by ratio
190
time *= ratio # In-place scaling
191
```
192
193
### Comparison Operations
194
195
Compare times using standard comparison operators.
196
197
```python { .api }
198
time1 < time2 # Earlier than
199
time1 <= time2 # Earlier than or equal
200
time1 == time2 # Equal times
201
time1 >= time2 # Later than or equal
202
time1 > time2 # Later than
203
time1 != time2 # Not equal
204
```
205
206
### String Representation
207
208
Convert times to various string formats.
209
210
```python { .api }
211
def __str__(self):
212
"""
213
Convert to SubRip format string.
214
215
Returns:
216
str: Time in "HH:MM:SS,mmm" format (negative times shown as 00:00:00,000)
217
"""
218
219
def __repr__(self):
220
"""
221
Convert to Python representation.
222
223
Returns:
224
str: "SubRipTime(hours, minutes, seconds, milliseconds)" format
225
"""
226
```
227
228
### Iteration Support
229
230
Iterate over time components.
231
232
```python { .api }
233
def __iter__(self):
234
"""
235
Iterate over time components.
236
237
Yields:
238
int: Hours, minutes, seconds, milliseconds in order
239
"""
240
```
241
242
## Usage Examples
243
244
### Creating Times
245
246
```python
247
import pysrt
248
from datetime import time
249
250
# Create from components
251
t1 = pysrt.SubRipTime(1, 30, 45, 500) # 01:30:45,500
252
print(t1) # "01:30:45,500"
253
254
# Create from string
255
t2 = pysrt.SubRipTime.from_string("00:02:15,750")
256
257
# Create from total milliseconds
258
t3 = pysrt.SubRipTime.from_ordinal(135500) # 00:02:15,500
259
260
# Create from datetime.time
261
py_time = time(14, 30, 15, 250000) # 250000 microseconds = 250 ms
262
t4 = pysrt.SubRipTime.from_time(py_time)
263
264
# Coerce from various formats
265
t5 = pysrt.SubRipTime.coerce("01:23:45,678")
266
t6 = pysrt.SubRipTime.coerce(90000) # 90 seconds in milliseconds
267
t7 = pysrt.SubRipTime.coerce({'minutes': 5, 'seconds': 30})
268
t8 = pysrt.SubRipTime.coerce((0, 1, 30, 0)) # tuple format
269
```
270
271
### Time Arithmetic
272
273
```python
274
# Basic arithmetic
275
start = pysrt.SubRipTime(0, 1, 0, 0) # 00:01:00,000
276
duration = pysrt.SubRipTime(0, 0, 3, 500) # 00:00:03,500
277
end = start + duration # 00:01:03,500
278
279
# Time differences
280
total_time = pysrt.SubRipTime(1, 30, 0, 0)
281
elapsed = pysrt.SubRipTime(0, 45, 30, 0)
282
remaining = total_time - elapsed # 00:44:30,000
283
284
# Scaling operations
285
original = pysrt.SubRipTime(0, 2, 0, 0) # 2 minutes
286
double_speed = original * 0.5 # 1 minute (half duration)
287
slow_motion = original * 2.0 # 4 minutes (double duration)
288
```
289
290
### Component Access
291
292
```python
293
time_obj = pysrt.SubRipTime(2, 15, 30, 750) # 02:15:30,750
294
295
# Access components
296
print(f"Hours: {time_obj.hours}") # 2
297
print(f"Minutes: {time_obj.minutes}") # 15
298
print(f"Seconds: {time_obj.seconds}") # 30
299
print(f"Milliseconds: {time_obj.milliseconds}") # 750
300
301
# Total milliseconds
302
print(f"Total ms: {time_obj.ordinal}") # 8130750
303
304
# Component modification
305
time_obj.hours = 3
306
time_obj.minutes = 0
307
print(time_obj) # "03:00:30,750"
308
309
# Iteration over components
310
hours, minutes, seconds, ms = time_obj
311
components = list(time_obj) # [3, 0, 30, 750]
312
```
313
314
### Time Shifting
315
316
```python
317
# Offset operations
318
time_obj = pysrt.SubRipTime(1, 0, 0, 0) # 01:00:00,000
319
320
# Add components
321
time_obj.shift(minutes=30, seconds=15) # 01:30:15,000
322
time_obj.shift(hours=-1, milliseconds=500) # 00:30:15,500
323
324
# Ratio scaling for framerate conversion
325
# Convert from 23.976 fps to 25 fps
326
time_obj.shift(ratio=25/23.976)
327
328
# In-place operations
329
time_obj += pysrt.SubRipTime(0, 0, 5, 0) # Add 5 seconds
330
time_obj -= pysrt.SubRipTime(0, 0, 2, 500) # Subtract 2.5 seconds
331
time_obj *= 1.1 # Scale by 10%
332
```
333
334
### Format Conversion
335
336
```python
337
# Convert to different formats
338
srt_time = pysrt.SubRipTime(14, 30, 15, 250)
339
340
# Standard Python time object
341
py_time = srt_time.to_time()
342
print(py_time) # 14:30:15.250000
343
344
# String representations
345
print(str(srt_time)) # "14:30:15,250"
346
print(repr(srt_time)) # "SubRipTime(14, 30, 15, 250)"
347
348
# Total seconds (with decimal)
349
total_seconds = srt_time.ordinal / 1000.0 # 52215.25
350
351
# Format for different systems
352
ffmpeg_format = str(srt_time).replace(',', '.') # "14:30:15.250"
353
```
354
355
### Validation and Error Handling
356
357
```python
358
try:
359
# Invalid format
360
bad_time = pysrt.SubRipTime.from_string("25:70:90,1500")
361
except pysrt.InvalidTimeString as e:
362
print(f"Invalid time format: {e}")
363
364
# Negative time handling
365
negative = pysrt.SubRipTime(0, 0, 5, 0) - pysrt.SubRipTime(0, 0, 10, 0)
366
print(negative.ordinal) # -5000 (internal representation)
367
print(str(negative)) # "00:00:00,000" (displayed as zero)
368
369
# Very large times
370
large_time = pysrt.SubRipTime(99, 59, 59, 999) # Maximum reasonable time
371
print(large_time) # "99:59:59,999"
372
```
373
374
### Advanced Usage
375
376
```python
377
# Time-based subtitle operations
378
def adjust_subtitle_timing(subs, delay_ms):
379
"""Add delay to all subtitles"""
380
delay = pysrt.SubRipTime.from_ordinal(delay_ms)
381
for sub in subs:
382
sub.start += delay
383
sub.end += delay
384
385
def synchronize_subtitles(subs, reference_time, actual_time):
386
"""Sync subtitles based on a reference point"""
387
ratio = actual_time.ordinal / reference_time.ordinal
388
for sub in subs:
389
sub.shift(ratio=ratio)
390
391
def find_gaps(subs, min_gap_ms=100):
392
"""Find gaps between subtitles"""
393
gaps = []
394
min_gap = pysrt.SubRipTime.from_ordinal(min_gap_ms)
395
396
for i in range(len(subs) - 1):
397
current_end = subs[i].end
398
next_start = subs[i + 1].start
399
gap = next_start - current_end
400
401
if gap > min_gap:
402
gaps.append((i, gap))
403
404
return gaps
405
406
# Usage
407
subs = pysrt.open('movie.srt')
408
adjust_subtitle_timing(subs, 2500) # 2.5 second delay
409
gaps = find_gaps(subs)
410
print(f"Found {len(gaps)} significant gaps")
411
```
412
413
## Constants
414
415
```python { .api }
416
TIME_PATTERN: str = '%02d:%02d:%02d,%03d' # String format pattern
417
SECONDS_RATIO: int = 1000 # Milliseconds per second
418
MINUTES_RATIO: int = 60000 # Milliseconds per minute
419
HOURS_RATIO: int = 3600000 # Milliseconds per hour
420
```