After the fix, the Easy Chart opens in historical mode with a valid Java date at each range endpoint: the start is eight days before today at midnight, and the end is today at midnight. The key is to keep values as java.util.Date objects throughout the binding path and convert to text only when a display or SQL string actually requires text.
Remove the quick fixes that change the data type
The usual failed fix is to format a date until it looks right. That changes the value into a string. A date property cannot accept that string without another conversion.
| Symptom | Likely cause | Reading to take | Next check |
|---|---|---|---|
| The displayed value looks correct, but the chart rejects it |
dateFormat returned a string |
Inspect the runtime type immediately after formatting | Remove formatting or convert the final string with toDate
|
A date dynamic property still needs toDate
|
The expression feeding it became a string before assignment | Check the expression's final return type, not the property's declared type | Return the original date directly when midnight normalization is unnecessary |
The Popup Calendar shows a value such as 12/08/2008 00:00:00 +0100 but rejects scripted text |
The visible representation was mistaken for the property type | Read whether the script produces java.util.Date or text |
Assign Date() or Calendar.getTime()
|
| Different clients open different ranges | The clients use different clock or time-zone settings | Compare the client time with SELECT NOW() from the selected database |
Choose one clock authority before building either endpoint |
| The chart opens with no useful historical interval | The start and end values are invalid, reversed, equal, or not connected to the chart's history range | Display both endpoint values and types beside the chart | Verify ordering, bindings, and historical mode |
A declared Date property controls what it can receive; it does not force every incoming expression to become a date. For example, this expression deliberately makes text and then parses that text back into a date:
toDate(dateFormat(dateArithmetic(now(0), -8, "day"), "yyyy-MM-dd 00:00:00"))
toDate is required there because dateFormat returns a string. It is not required merely because the destination is a Date property.
Check the type at every range boundary
Start at the producer and follow the value to the chart. The client currentdatetime tag, the now() expression function, and values from the Date Range control are all java.util.Date values. SQL DATETIME and TIMESTAMP results also become Java Dates. Python date objects are a different type.
- Place
now(0)in a temporary label or date-typed dynamic property. If it evaluates, the expression engine is producing the correct base type. - Place
dateArithmetic(now(0), -8, "day")in a second temporary property. If it evaluates, date arithmetic is still returning a Date. - Inspect the final expression assigned to
initialDateStartandinitialDateEnd. If its last operation isdateFormat, the result is text. If its last operation istoDate, the result is a Date. - Inspect the values delivered by the Date Range control. Pass those Date values directly unless the range needs normalization.
- Follow both bindings into the Easy Chart's historical start and end inputs. If the source values are valid but the destination remains unchanged, repair the binding rather than adding more conversions.
A java.util.Date represents a point in time. Text such as 12/08/2008 00:00:00 +0100 is only one formatted representation of that point. Do not copy the representation into a Date property and expect the component to parse it automatically.
Choose the clock before calculating the range
Take two readings: the client time and the database time. If they agree within the operational tolerance for the application, either can anchor the range. If they differ, decide which system owns historical reporting boundaries.
Using now(0) makes the client runtime the clock authority. This is simple, but different client clock or time-zone settings can produce different boundaries. Reading NOW() from the database makes the selected database server the authority:
try:
currentTime = fpmi.db.runScalarQuery("SELECT NOW() FROM myDatabase")
from java.text import SimpleDateFormat
dateAndTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(currentTime)
print dateAndTime
except:
print "SQL error"
The scalar query returns a Java Date when the SQL result is a DATETIME or TIMESTAMP. The formatter then turns it into text for printing. Keep currentTime, not dateAndTime, when feeding a date property.
If the query fails or returns no value, stop that branch. Confirm the database connection, selected database, and scalar result before calculating the start date. Do not silently fall back to a client clock when synchronized reporting boundaries matter; that creates ranges whose origin changes with connection state.
Build midnight endpoints without losing the Date type
First decide whether the required range is a rolling eight-day interval or calendar-midnight boundaries. The two expressions below create calendar boundaries: eight days before the current date at 00:00:00, and the current date at 00:00:00.
initialDateStart = toDate(
dateFormat(
dateArithmetic(now(0), -8, "day"),
"yyyy-MM-dd 00:00:00"
)
)
initialDateEnd = toDate(
dateFormat(
now(0),
"yyyy-MM-dd 00:00:00"
)
)
Read the displayed endpoints after evaluation. The start must precede the end, and both must show midnight in the time zone used by the client formatter and parser. If the end equals today's midnight, the interval excludes the current day's later data when the chart treats the end as an upper boundary. If production needs data through the present moment, keep the start normalization but feed the unformatted now(0) Date to the end.
A formatter and parser also introduce locale and time-zone dependencies. When the application needs only an offset from the current instant, use dateArithmetic directly and avoid the text round trip. Use the format-and-parse pattern only when the calendar boundary is intentional.
Use Java Calendar for scripted component dates
For the Popup Calendar, assign a Java Date to its date property. To initialize it to the current runtime time:
from java.util import Date
datePopup = event.source.parent.getComponent("DatePopup")
datePopup.date = Date()
Take the resulting component reading. If it changes to the current time, the component path and assignment type are correct. If it does not change, verify the component name and container path before changing the date logic.
Use java.util.Calendar when the script must set individual calendar fields:
from java.util import Calendar
cal = Calendar.getInstance()
cal.set(2008, 4, 23, 8, 0)
datePopup = event.source.parent.getComponent("DatePopup")
datePopup.date = cal.getTime()
Calendar.getTime() returns the java.util.Date required by the component. Java Calendar month values are zero-based, so month value 4 represents May. Read the displayed date after assignment; if it is one month away from the intended date, correct the month input rather than applying string formatting.
Keep SQL formatting outside the chart path
Formatting is appropriate when a genuine string consumer needs a date string. This script creates the text form yyyy-MM-dd:
from java.util import Calendar
from java.text import SimpleDateFormat
today = Calendar.getInstance().getTime()
todaysDate = SimpleDateFormat("yyyy-MM-dd").format(today)
print todaysDate
Use todaysDate for display or for a database interface that explicitly requires text. For SQL updates, bind the Date through the database layer when parameter binding is available; this avoids date-literal parsing and quoting problems. If an existing update must receive a string, verify the database's expected date format and keep that formatted value separate from initialDateStart, initialDateEnd, and component date properties.
The decision is simple: a chart, calendar, expression date operation, or date-typed property receives a Java Date; a label, log line, or explicitly textual SQL field receives a formatted string. Never reuse one variable for both roles.
Apply the resolving range and prove it under history
- Select the time authority. Use
now(0)for client time or the Java Date returned bySELECT NOW()for database time. - Create two root-container dynamic properties named
initialDateStartandinitialDateEnd, both with the Date type. - For an eight-day, midnight-to-midnight range based on client time, assign the format-and-parse expressions shown above. For a range ending now, assign
now(0)directly toinitialDateEnd. - Temporarily display both properties. Confirm that each value contains a date and time, the start is earlier than the end, and the intended time-zone boundary appears.
- Bind the two dynamic properties to the Easy Chart inputs that control the historical start and end. Keep the chart in historical mode.
- Open the window from a fresh client session. Confirm that the chart receives the values during startup rather than only after a manual date change.
- Change the Date Range control and verify that both endpoints remain Java Dates as they travel to the chart.
- Check the oldest and newest plotted timestamps against the requested interval. If properties are correct but no samples appear, diagnose history availability and chart binding separately from date conversion.
Get it running, then fix it properly: remove temporary labels only after a fresh startup reproduces the correct range. Repeat the startup test from another client when multiple users share the application. A difference between clients points to clock, time-zone, startup-order, or binding context rather than the Java Date class.
FAQ
What happens if I assign dateFormat directly to a Date property?
dateFormat returns a string, so the assignment has a type mismatch. Remove dateFormat or wrap the formatted result in toDate when midnight text normalization is intentional.
What happens if initialDateEnd is today at midnight?
The end represents 00:00:00, not the current time, so later samples from today fall beyond that boundary. Use the Date returned directly by now(0) when the chart must run through the present moment.
What happens if clients have different system times?
Ranges calculated with now(0) can differ between clients. Use the Java Date returned by SELECT NOW() when the database server must provide one shared time authority.
What happens if I assign a formatted Popup Calendar value in Python?
The component receives text instead of the Java Date expected by its date property. Assign Date() for the current time or Calendar.getTime() for a constructed date.
What happens if both endpoints are Dates but the Easy Chart still starts incorrectly?
Stop here if the endpoint readings are valid, ordered, bound to the historical range, and still fail during a fresh client startup. Capture the two values, their runtime types, the client and database times, the chart mode, and the binding configuration, then escalate to official product support. Do not add more string conversions while the binding or startup sequence remains unresolved.