Last active
October 25, 2024 19:25
-
-
Save yeiichi/153e2b23fdf3ff41849a284633893835 to your computer and use it in GitHub Desktop.
Create a filename with the epoch time / Parse an epoch-filename.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import re | |
import time | |
from datetime import datetime, timezone | |
class FnameWithEpoch: | |
"""Create a filename with the epoch time / Parse an epoch-filename. | |
Reference: | |
File Naming Conventions | |
https://datamanagement.hms.harvard.edu/plan-design/file-naming-conventions | |
""" | |
@staticmethod | |
def fname_with_epoch(prefix, suffix): | |
"""Create a filename in "prefix_current-epoch_suffix" format. | |
Args: | |
prefix (str): Prefix of filename. | |
suffix (str): Suffix of filename. | |
Returns: | |
str: Filename in "prefix_epoch_suffix" format. | |
""" | |
now_epoch = int(time.time() * 1000) # milliseconds | |
return f'{prefix}_{now_epoch}{suffix}' | |
@staticmethod | |
def epoch_fname_to_dttm(fname, trunk=3): | |
"""Parse prefix_epoch-msec.suffix -> prefix_yyyymmddHHMMSSmsec.suffix in UTC. | |
Args: | |
trunk (int): Number of chars to be truncated from the dttm string's tail. | |
fname (str): Filename in "prefix_epoch_suffix" format. | |
Returns: | |
str: Filename in "prefix_yyyymmddHHMM.suffix" format. | |
Example: | |
data_0000003600123.txt -> data_19700101010000123.txt | |
Reference: | |
Format a datetime into a string with milliseconds | |
https://stackoverflow.com/a/18406412/11042987 | |
""" | |
pattern = re.compile(r'\D(\d{13})\D') # epoch time in milliseconds | |
pattern_found = pattern.search(fname) | |
if pattern_found: | |
epoch_string = pattern_found.group(1) | |
dttm_string = datetime.fromtimestamp( | |
int(epoch_string) / 1000, timezone.utc).strftime('%Y%m%d%H%M%S%f')[:int(-trunk)] | |
new_name = fname.replace(epoch_string, dttm_string) | |
print(f'\033[93mRenamed: {fname} -> {new_name}') | |
return new_name | |
else: | |
return fname | |
def menu(): | |
print(''' | |
\033[93mMENU | |
[C]reate fname: New filename in "prefix_current-epoch_suffix" format. | |
[P]arse fname : "prefix_epoch-msec.suffix" -> "prefix_yyyymmddHHMMSSmsec.suffix". | |
\033[0m''', end='') | |
res = input('Create fname [C] or Parse fname [P]? >> ').lower() | |
# noinspection PyCompatibility | |
match res: | |
case 'c': | |
return FnameWithEpoch.fname_with_epoch(input('Prefix? >> '), input('Suffix? >> ')) | |
case 'p': | |
return FnameWithEpoch.epoch_fname_to_dttm(input('Filename? >> ')) | |
case _: | |
raise ValueError(f'Invalid input: {res}') | |
if __name__ == '__main__': | |
print(menu()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment