Skip to main content
Glama

convert_time

Convert time between timezones using IANA names or system time, handling 24-hour format inputs for accurate timezone calculations.

Instructions

Convert time between timezones (defaults to system time for source/target)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
source_timezoneYesSource timezone. Use 'system' or 'local' for user's local time (Etc/UTC), or IANA names like 'America/New_York', 'UTC'. System time is the most practical default.
target_timezoneYesTarget timezone. Use 'system' or 'local' for user's local time (Etc/UTC), or IANA names like 'Asia/Tokyo', 'UTC'. System time is the most practical default.
timeYesTime to convert in 24-hour format (HH:MM)

Implementation Reference

  • Core implementation of the convert_time tool in TimeServer class. Parses input time, handles timezone resolution including 'system'/'local', converts using pytz, computes time difference, and returns structured TimeConversionResult.
    def convert_time(
        self, source_tz: str, time_str: str, target_tz: str
    ) -> TimeConversionResult:
        """Convert time between timezones (defaults to system time)"""
        local_tz_name = str(get_local_tz())
        
        # Handle system/local timezone references
        actual_source_tz = source_tz
        if source_tz.lower() in ["system", "local"]:
            actual_source_tz = local_tz_name
        
        actual_target_tz = target_tz
        if target_tz.lower() in ["system", "local"]:
            actual_target_tz = local_tz_name
            
        source_timezone = get_zoneinfo(actual_source_tz)
        target_timezone = get_zoneinfo(actual_target_tz)
    
        try:
            parsed_time = datetime.strptime(time_str, "%H:%M").time()
        except ValueError:
            raise ValueError("Invalid time format. Expected HH:MM [24-hour format]")
    
        now = datetime.now(source_timezone)
        source_time = datetime(
            now.year,
            now.month,
            now.day,
            parsed_time.hour,
            parsed_time.minute,
            tzinfo=source_timezone,
        )
    
        target_time = source_time.astimezone(target_timezone)
        source_offset = source_time.utcoffset() or timedelta()
        target_offset = target_time.utcoffset() or timedelta()
        hours_difference = (target_offset - source_offset).total_seconds() / 3600
    
        if hours_difference.is_integer():
            time_diff_str = f"{hours_difference:+.1f}h"
        else:
            # For fractional hours like Nepal's UTC+5:45
            time_diff_str = f"{hours_difference:+.2f}".rstrip("0").rstrip(".") + "h"
    
        # Create formatted timezone displays
        source_formatted = source_time.strftime("%B %d, %Y at %I:%M:%S %p")
        target_formatted = target_time.strftime("%B %d, %Y at %I:%M:%S %p")
        
        if source_tz.lower() in ["system", "local"]:
            source_formatted += f" (System Time - {local_tz_name})"
            display_source_tz = f"System ({local_tz_name})"
        else:
            source_formatted += f" ({source_tz})"
            display_source_tz = source_tz
            
        if target_tz.lower() in ["system", "local"]:
            target_formatted += f" (System Time - {local_tz_name})"
            display_target_tz = f"System ({local_tz_name})"
        else:
            target_formatted += f" ({target_tz})"
            display_target_tz = target_tz
    
        return TimeConversionResult(
            source=TimeResult(
                timezone=display_source_tz,
                datetime=source_time.isoformat(timespec="seconds"),
                formatted_timezone=source_formatted,
                day_of_week=source_time.strftime("%A"),
                is_dst=bool(source_time.dst()),
            ),
            target=TimeResult(
                timezone=display_target_tz,
                datetime=target_time.isoformat(timespec="seconds"),
                formatted_timezone=target_formatted,
                day_of_week=target_time.strftime("%A"),
                is_dst=bool(target_time.dst()),
            ),
            time_difference=time_diff_str,
        )
  • MCP tool registration in list_tools(). Defines name, description, and input schema (source_timezone, time HH:MM, target_timezone).
    Tool(
        name=TimeTools.CONVERT_TIME.value,
        description="Convert time between timezones (defaults to system time for source/target)",
        inputSchema={
            "type": "object",
            "properties": {
                "source_timezone": {
                    "type": "string",
                    "description": f"Source timezone. Use 'system' or 'local' for user's local time ({local_tz}), or IANA names like 'America/New_York', 'UTC'. System time is the most practical default.",
                },
                "time": {
                    "type": "string",
                    "description": "Time to convert in 24-hour format (HH:MM)",
                },
                "target_timezone": {
                    "type": "string", 
                    "description": f"Target timezone. Use 'system' or 'local' for user's local time ({local_tz}), or IANA names like 'Asia/Tokyo', 'UTC'. System time is the most practical default.",
                },
            },
            "required": ["source_timezone", "time", "target_timezone"],
        },
    ),
    Tool(
  • Tool dispatch logic in _execute_tool(). Validates inputs using helper functions and calls the TimeServer.convert_time handler.
    case TimeTools.CONVERT_TIME.value:
        if not all(
            k in arguments
            for k in ["source_timezone", "time", "target_timezone"]
        ):
            raise ValueError("Missing required arguments")
    
        # Validate inputs with helpful error messages
        source_tz = validate_timezone(arguments["source_timezone"])
        target_tz = validate_timezone(arguments["target_timezone"])
        validated_time = validate_time_format(arguments["time"])
    
        result = time_server.convert_time(source_tz, validated_time, target_tz)
  • Pydantic model defining the output structure for convert_time: source/target TimeResult and time_difference.
    class TimeConversionResult(BaseModel):
        source: TimeResult
        target: TimeResult
        time_difference: str
  • Helper function to validate input time string format (HH:MM, 00:00-23:59), used in convert_time execution.
    def validate_time_format(time_str: str) -> str:
        """Validate time format and provide helpful error messages."""
        if not isinstance(time_str, str):
            raise ValueError("Time must be a string")
    
        # Check HH:MM format
        if not time_str or len(time_str) != 5 or time_str[2] != ':':
            raise ValueError(
                f"Invalid time format '{time_str}'. Expected 24-hour format HH:MM (00:00-23:59)"
            )
    
        try:
            hours, minutes = time_str.split(':')
            hours = int(hours)
            minutes = int(minutes)
    
            if not (0 <= hours <= 23):
                raise ValueError(f"Hours must be between 00-23, got {hours:02d}")
    
            if not (0 <= minutes <= 59):
                raise ValueError(f"Minutes must be between 00-59, got {minutes:02d}")
    
            return time_str
        except ValueError as e:
            if "too many values" in str(e) or "not enough values" in str(e):
                raise ValueError(
                    f"Invalid time format '{time_str}'. Expected HH:MM format (e.g., 14:30)"
                )
            raise

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/n0zer0d4y/chronos-protocol'

If you have feedback or need assistance with the MCP directory API, please join our Discord server