CoolFace
Apppublic

arcticaurora/TimeTool

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py177 linesDownload Raw Back to root
1from fastapi import FastAPI, HTTPException, Body2from fastapi.middleware.cors import CORSMiddleware3 4 5from pydantic import BaseModel, Field6from datetime import datetime, timezone7from typing import Literal8import pytz9from dateutil import parser as dateutil_parser10 11app = FastAPI(12    title="Secure Time Utilities API",13    version="1.0.0",14    description="Provides secure UTC/local time retrieval, formatting, timezone conversion, and comparison.",15    servers=[{"url": "https://arcticaurora-timetool.hf.space"}]16)17 18 19origins = ["*"]20 21app.add_middleware(22    CORSMiddleware,23    allow_origins=origins,24    allow_credentials=True,25    allow_methods=["*"],26    allow_headers=["*"],27)28 29 30# -------------------------------31# Pydantic models32# -------------------------------33 34 35class FormatTimeInput(BaseModel):36    format: str = Field(37        "%Y-%m-%d %H:%M:%S", description="Python strftime format string"38    )39    timezone: str = Field(40        "UTC", description="IANA timezone name (e.g., UTC, America/New_York)"41    )42 43 44class ConvertTimeInput(BaseModel):45    timestamp: str = Field(46        ..., description="ISO 8601 formatted time string (e.g., 2024-01-01T12:00:00Z)"47    )48    from_tz: str = Field(49        ..., description="Original IANA time zone of input (e.g. UTC or Europe/Berlin)"50    )51    to_tz: str = Field(..., description="Target IANA time zone to convert to")52 53 54class ElapsedTimeInput(BaseModel):55    start: str = Field(..., description="Start timestamp in ISO 8601 format")56    end: str = Field(..., description="End timestamp in ISO 8601 format")57    units: Literal["seconds", "minutes", "hours", "days"] = Field(58        "seconds", description="Unit for elapsed time"59    )60 61 62class ParseTimestampInput(BaseModel):63    timestamp: str = Field(64        ..., description="Flexible input timestamp string (e.g., 2024-06-01 12:00 PM)"65    )66    timezone: str = Field(67        "UTC", description="Assumed timezone if none is specified in input"68    )69 70 71# -------------------------------72# Routes73# -------------------------------74 75 76@app.get("/get_current_utc_time", summary="Current UTC time")77def get_current_utc():78    """79    Returns the current time in UTC in ISO format.80    """81    return {"utc": datetime.utcnow().replace(tzinfo=timezone.utc).isoformat()}82 83 84@app.get("/get_current_local_time", summary="Current Local Time")85def get_current_local():86    """87    Returns the current time in local timezone in ISO format.88    """89    return {"local_time": datetime.now().isoformat()}90 91 92@app.post("/format_time", summary="Format current time")93def format_current_time(data: FormatTimeInput):94    """95    Return the current time formatted for a specific timezone and format.96    """97    try:98        tz = pytz.timezone(data.timezone)99    except Exception:100        raise HTTPException(101            status_code=400, detail=f"Invalid timezone: {data.timezone}"102        )103    now = datetime.now(tz)104    try:105        return {"formatted_time": now.strftime(data.format)}106    except Exception as e:107        raise HTTPException(status_code=400, detail=f"Invalid format string: {e}")108 109 110@app.post("/convert_time", summary="Convert between timezones")111def convert_time(data: ConvertTimeInput):112    """113    Convert a timestamp from one timezone to another.114    """115    try:116        from_zone = pytz.timezone(data.from_tz)117        to_zone = pytz.timezone(data.to_tz)118    except Exception as e:119        raise HTTPException(status_code=400, detail=f"Invalid timezone: {e}")120 121    try:122        dt = dateutil_parser.parse(data.timestamp)123        if dt.tzinfo is None:124            dt = from_zone.localize(dt)125        else:126            dt = dt.astimezone(from_zone)127        converted = dt.astimezone(to_zone)128        return {"converted_time": converted.isoformat()}129    except Exception as e:130        raise HTTPException(status_code=400, detail=f"Invalid timestamp: {e}")131 132 133@app.post("/elapsed_time", summary="Time elapsed between timestamps")134def elapsed_time(data: ElapsedTimeInput):135    """136    Calculate the difference between two timestamps in chosen units.137    """138    try:139        start_dt = dateutil_parser.parse(data.start)140        end_dt = dateutil_parser.parse(data.end)141        delta = end_dt - start_dt142    except Exception as e:143        raise HTTPException(status_code=400, detail=f"Invalid timestamps: {e}")144 145    seconds = delta.total_seconds()146    result = {147        "seconds": seconds,148        "minutes": seconds / 60,149        "hours": seconds / 3600,150        "days": seconds / 86400,151    }152 153    return {"elapsed": result[data.units], "unit": data.units}154 155 156@app.post("/parse_timestamp", summary="Parse and normalize timestamps")157def parse_timestamp(data: ParseTimestampInput):158    """159    Parse human-friendly input timestamp and return standardized UTC ISO time.160    """161    try:162        tz = pytz.timezone(data.timezone)163        dt = dateutil_parser.parse(data.timestamp)164        if dt.tzinfo is None:165            dt = tz.localize(dt)166        dt_utc = dt.astimezone(pytz.utc)167        return {"utc": dt_utc.isoformat()}168    except Exception as e:169        raise HTTPException(status_code=400, detail=f"Could not parse: {e}")170 171 172@app.get("/list_time_zones", summary="All valid time zones")173def list_time_zones():174    """175    Return a list of all valid IANA time zones.176    """177    return pytz.all_timezones