Class SimpleDateFormat

All Implemented Interfaces:
Serializable, Cloneable

@Deprecated public class SimpleDateFormat extends SimpleDateFormat
Deprecated.
This is transitional scaffolding produced by the import-swap. It faithfully preserves a Swing anti-pattern (a shared mutable formatter) so the app runs; hand-written and stage-3 code should format dates with com.vaadin.swingbridge.surrogates.util.BrowserDateUtils.formatAsISODate/formatAsDate or DateTimeFormatter instead, which are stateless.
Import-swap emulator for SimpleDateFormat (java.text.SimpleDateFormat → vaadinx.text.SimpleDateFormat).

Why this exists. The Swing idiom static final SimpleDateFormat F = new SimpleDateFormat("yyyy-MM-dd") is safe on the desktop — one JVM, one user, one EDT touches it — but breaks two ways on the server:

  1. Thread-safety. format/parse mutate an internal Calendar; a static instance is now shared across users and across virtual threads, so concurrent calls corrupt each other.
  2. Zone-correctness. A plain new SimpleDateFormat(...) formats in the server JVM zone, not the user's browser zone — a silent day-off bug (server UTC, user UTC+13 → yesterday). It doesn't even throw; it's just quietly wrong.

How it stays correct while staying a drop-in. This class extends SimpleDateFormat so it's assignable everywhere a JDK DateFormat/Format is, but it holds no live formatting state of its own. It keeps a session-independent configuration template (a plain JDK SimpleDateFormat used only as a prototype, never to format), and every format/parse operates on a per-session backing cloned from that template and pinned to the browser's time zone. The instance itself is therefore safe to share JVM-wide (as a static), because all mutable state lives in the session, not on the instance.

Thread-safety contract. Formatting/parsing from a Vaadin UI thread (or an EHelper.callSwing(Runnable) continuation) is fully thread-safe and browser-zoned: the backing is reached only under the Vaadin session lock, which serialises all such access. On a background thread (no VaadinSession) it degrades to a per-call throwaway pinned to the server default zone — race-free (thread-local) and never throwing, i.e. at least as safe as the original code and using the exact zone the original static instance used on that same thread.

Configuration / freeze model. Construction and configuration (applyPattern, setLenient, setTimeZone, …) with no current session write the template — this is the static-initialiser window and never throws or reads a zone. Configuration from a live UI thread is applied to that session's backing only (session-local; no cross-user leak). The template freezes on first use (first format/parse or first backing build); after that, reconfiguring from a background thread throws IllegalStateException — silently rewriting a shared formatter for every user is corruption the original single-JVM app never risked, so it fails loud rather than degrading.

The backing is zoned via TimeZone.getTimeZone(java.time.ZoneId) — the same arithmetic the DatePicker-backed surrogates convert with, so a picked date formats as the day picked in every year, pre-1900 included.

Emulator-only — no surrogate. Like Timer / SwingWorker (D_timer_swingworker), SimpleDateFormat is not a Component and has no Vaadin peer; the stage-3 rewrite drops it entirely for java.time / SHelper.

See Also: