如何将Gregorian Calendar的toString输出字符串解析为Gregorian Calendar对象?
Hey there, let's work through this problem. First, a critical note: using GregorianCalendar.toString() for database persistence is not a recommended practice. That string is designed for debugging purposes only—its format isn't standardized and can change across different Java versions, which will make parsing fragile down the line. But if you already have these strings stored and need to convert them back, here's how to handle it.
Emergency Fix: Parse the Existing toString() String
The toString() output includes a time= field that holds the timestamp in milliseconds (when the calendar has a set time). We can use a regex to extract this value and rebuild the calendar:
import java.util.GregorianCalendar; import java.util.regex.Matcher; import java.util.regex.Pattern; public class CalendarStringParser { public static GregorianCalendar parseFromString(String calToString) { // Regex to capture the numeric time value after "time=" Pattern timePattern = Pattern.compile("time=(\\d+)"); Matcher matcher = timePattern.matcher(calToString); if (matcher.find()) { long timeMillis = Long.parseLong(matcher.group(1)); GregorianCalendar calendar = new GregorianCalendar(); calendar.setTimeInMillis(timeMillis); // Optional: If you need to restore timezone/leniency settings, you'd need to parse more fields // For example, extract the zone field with another regex and set it, but this gets messy fast return calendar; } else { // If the string has "time=?" (like your example), the calendar didn't have a set time throw new IllegalArgumentException("Cannot parse calendar string: no valid time value found"); } } public static void main(String[] args) { String sampleStr = "java.util.GregorianCalendar[time=1699999999000,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=java.util.SimpleTimeZone[id=GMT,offset=0,dstSavings=3600000,useDaylight=false,startYear=0,startMode=0,startMonth=0,startDay=0,startDayOfWeek=0,startTime=0,startTimeMode=0,endMode=0,endMonth=0,endDay=0,endDayOfWeek=0,endTime=0,endTimeMod...]"; GregorianCalendar parsedCal = parseFromString(sampleStr); System.out.println("Parsed time: " + parsedCal.getTime()); } }
Limitations of This Approach
- If your string shows
time=?(meaning the original calendar had no set time), this method will fail—there's no valid timestamp to extract. - Restoring other settings (like timezone, leniency, or daylight savings rules) is extremely difficult because the
toString()format for these fields is unstructured and not meant for parsing. You'll likely lose those details.
The Better Long-Term Solution
Instead of storing the toString() output, use one of these reliable serialization methods for your GregorianCalendar:
- Store the timestamp: Save
cal.getTimeInMillis()as aBIGINTin your database. To restore, create a newGregorianCalendarand callsetTimeInMillis(longValue). This is the simplest and most robust option. - Store an ISO 8601 string: Format the calendar's time into a standardized string (e.g.,
2023-11-13T12:34:56.789Z) usingSimpleDateFormator Java 8+ date/time APIs:
This preserves human-readability and works across systems.// Formatting SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); String isoStr = isoFormat.format(cal.getTime()); // Parsing back Date date = isoFormat.parse(isoStr); GregorianCalendar restoredCal = new GregorianCalendar(); restoredCal.setTime(date);
内容的提问来源于stack exchange,提问作者whittaker Ben

