You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Windows时区名称格式获取Java的TimeZone对象

Convert Windows Timezone Display Strings to Java TimeZone

Got it, let's tackle this problem. The Windows timezone display strings you're working with (like (GMT+10:00) Brisbane) don't directly map to Java's standard Olson timezone IDs (the ones used by TimeZone.getTimeZone()). We need to build a way to translate these strings into valid Java TimeZone objects, and there are two reliable approaches depending on your use case.

Approach 1: Auto-Matching via Offset and Keyword Matching

This method parses the GMT offset from the Windows string, fetches all Java timezones with that offset, then matches against the city/region name in the string to find the best fit. It works for most common cases without pre-configured mappings.

Step-by-Step Implementation

  1. Parse the raw GMT offset from the input string (convert to milliseconds, which Java uses internally).
  2. Extract key identifiers (city/region names) from the string's display portion.
  3. Match against candidate timezones with the same offset, checking both the timezone ID and its display name for keyword matches.

Here's the code:

import java.util.regex.*;
import java.util.*;

public class WindowsTimeZoneConverter {

    // Parse the GMT offset from the Windows timezone string (returns milliseconds)
    private static int parseRawOffset(String windowsTzStr) {
        Pattern offsetPattern = Pattern.compile("\\(GMT([+-]?\\d{1,2}(?::\\d{2})?)\\)");
        Matcher matcher = offsetPattern.matcher(windowsTzStr);
        
        if (matcher.find()) {
            String offsetStr = matcher.group(1);
            if (offsetStr.isEmpty()) {
                return 0; // Handles "(GMT) ..." case
            }
            
            String[] parts = offsetStr.split(":");
            int hours = Integer.parseInt(parts[0]);
            int minutes = parts.length > 1 ? Integer.parseInt(parts[1]) : 0;
            return (hours * 3600 + minutes * 60) * 1000;
        }
        throw new IllegalArgumentException("Invalid Windows timezone string: " + windowsTzStr);
    }

    // Extract keywords (city/region names) from the display portion of the string
    private static String extractKeywords(String windowsTzStr) {
        int nameStartIdx = windowsTzStr.indexOf(") ") + 2;
        if (nameStartIdx <= 1) {
            throw new IllegalArgumentException("Invalid Windows timezone string: " + windowsTzStr);
        }
        
        String namePart = windowsTzStr.substring(nameStartIdx);
        // Split off the description part if present (e.g., "Greenwich Mean Time : Dublin...")
        if (namePart.contains(" : ")) {
            namePart = namePart.split(" : ")[1];
        }
        return namePart.toLowerCase().trim();
    }

    // Convert Windows display string to Java TimeZone
    public static TimeZone convert(String windowsTzStr) {
        int rawOffset = parseRawOffset(windowsTzStr);
        String keywords = extractKeywords(windowsTzStr);
        String[] candidateIds = TimeZone.getAvailableIDs(rawOffset);

        // First try matching keywords in timezone ID or display name
        for (String id : candidateIds) {
            TimeZone tz = TimeZone.getTimeZone(id);
            if (id.toLowerCase().contains(keywords) 
                || tz.getDisplayName().toLowerCase().contains(keywords)) {
                return tz;
            }
            // Fallback: match the city part of the Olson ID (e.g., "Brisbane" from "Australia/Brisbane")
            String citySegment = id.substring(id.lastIndexOf('/') + 1).toLowerCase();
            if (keywords.contains(citySegment)) {
                return tz;
            }
        }

        // If no exact match, return the first candidate (or throw an error if preferred)
        if (candidateIds.length > 0) {
            return TimeZone.getTimeZone(candidateIds[0]);
        }
        throw new IllegalArgumentException("No matching Java TimeZone found for: " + windowsTzStr);
    }

    // Test the converter
    public static void main(String[] args) {
        // Test your examples
        System.out.println(convert("(GMT+10:00) Brisbane").getID()); // Australia/Brisbane
        System.out.println(convert("(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London").getID()); // Europe/London
        System.out.println(convert("(GMT+01:00) Brussels, Copenhagen, Madrid, Paris").getID()); // Europe/Paris
        System.out.println(convert("(GMT-09:00) Alaska").getID()); // America/Anchorage
    }
}

Approach 2: Predefined Mapping Table

For maximum accuracy (especially if you're dealing with a fixed set of timezones), create a direct mapping between Windows display strings and Java Olson IDs. This avoids any ambiguity from overlapping offsets or similar names.

Example Implementation

import java.util.*;

public class WindowsTimeZoneConverter {
    private static final Map<String, String> WINDOWS_TO_JAVA_TZ_MAP = new HashMap<>();

    // Initialize the mapping with your target timezones
    static {
        WINDOWS_TO_JAVA_TZ_MAP.put("(GMT+10:00) Brisbane", "Australia/Brisbane");
        WINDOWS_TO_JAVA_TZ_MAP.put("(GMT) Greenwich Mean Time : Dublin, Edinburgh, Lisbon, London", "Europe/London");
        WINDOWS_TO_JAVA_TZ_MAP.put("(GMT+01:00) Brussels, Copenhagen, Madrid, Paris", "Europe/Paris");
        WINDOWS_TO_JAVA_TZ_MAP.put("(GMT-09:00) Alaska", "America/Anchorage");
        // Add more mappings as needed
    }

    public static TimeZone convert(String windowsTzStr) {
        String javaTzId = WINDOWS_TO_JAVA_TZ_MAP.get(windowsTzStr);
        if (javaTzId == null) {
            // Fall back to auto-matching if the string isn't in the map
            return autoMatch(windowsTzStr); // Reuse the auto-match method from Approach 1
        }
        return TimeZone.getTimeZone(javaTzId);
    }

    // Reuse the autoMatch method from Approach 1 here...
}

Notes

  • Java Version: Use Java 8+ for up-to-date timezone data (tzdata), which includes more accurate mappings and recent timezone changes.
  • Localization: If your app runs on non-English Windows systems, the display strings will be in the system language (e.g., Chinese for "布里斯班"). For these cases, you'll need to extend the mapping table or use system APIs to fetch the Windows internal timezone ID (e.g., via PowerShell Get-TimeZone) and convert that to Java's timezone ID.

内容的提问来源于stack exchange,提问作者questp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:27:51