Time Expressions¶
PIPolars supports flexible time specifications using PI time expressions,
Python datetime objects, or the AFTime helper class.
PI Time Expression Syntax¶
PI time expressions are strings that specify absolute or relative times. PIPolars passes these to the PI AF SDK for parsing.
Relative Time Expressions¶
Expression |
Description |
|---|---|
|
Now (current time) |
|
1 hour ago |
|
1 day ago |
|
7 days ago |
|
30 days ago |
|
1 week ago |
|
2 months ago |
|
1 year ago |
|
1 hour from now |
|
1 day ago plus 6 hours |
Named Time Expressions¶
Expression |
Description |
|---|---|
|
Today at midnight (start of day) |
|
Yesterday at midnight |
|
Today at 8:00 AM |
|
Yesterday at 5:00 PM |
|
Start of yesterday (same as |
Absolute Time Expressions¶
Expression |
Description |
|---|---|
|
January 15, 2024 at midnight |
|
January 15, 2024 at 10:30:00 |
|
Same (with space separator) |
|
Alternative date format |
|
US date format |
Using Time Expressions¶
In Direct Methods¶
with PIClient("my-pi-server") as client:
# Relative expressions
df = client.recorded_values("SINUSOID", "*-1d", "*")
df = client.recorded_values("SINUSOID", "*-7d", "*")
# Named expressions
df = client.recorded_values("SINUSOID", "t", "*") # Today
df = client.recorded_values("SINUSOID", "y", "t") # Yesterday
# Absolute expressions
df = client.recorded_values(
"SINUSOID",
"2024-01-01",
"2024-01-31"
)
# Combination
df = client.recorded_values(
"SINUSOID",
"2024-01-15T08:00:00",
"*"
)
In Query Builder¶
with PIClient("my-pi-server") as client:
# Using time_range
df = (
client.query("SINUSOID")
.time_range("*-1d", "*")
.recorded()
.to_dataframe()
)
# Using convenience methods
df = (
client.query("SINUSOID")
.last(hours=24)
.recorded()
.to_dataframe()
)
df = (
client.query("SINUSOID")
.today()
.recorded()
.to_dataframe()
)
The AFTime Class¶
PIPolars provides the AFTime class for programmatic time construction:
from pipolars import AFTime
# Create from expression
now = AFTime("*")
yesterday = AFTime("y")
# Class methods
now = AFTime.now() # Current time
today = AFTime.today() # Today at midnight
yesterday = AFTime.yesterday() # Yesterday at midnight
# Relative time
one_day_ago = AFTime.ago(days=1)
two_hours_ago = AFTime.ago(hours=2)
complex_ago = AFTime.ago(days=1, hours=6, minutes=30)
Using AFTime in Queries¶
from pipolars import PIClient, AFTime
with PIClient("my-pi-server") as client:
start = AFTime.ago(days=7)
end = AFTime.now()
df = client.recorded_values(
"SINUSOID",
start=start,
end=end
)
Python datetime Objects¶
You can also use Python datetime objects:
from datetime import datetime, timedelta
from pipolars import PIClient
with PIClient("my-pi-server") as client:
now = datetime.now()
one_day_ago = now - timedelta(days=1)
df = client.recorded_values(
"SINUSOID",
start=one_day_ago,
end=now
)
Timezone Handling¶
from datetime import datetime
from zoneinfo import ZoneInfo
# Create timezone-aware datetime
tz = ZoneInfo("America/New_York")
start = datetime(2024, 1, 15, 8, 0, tzinfo=tz)
end = datetime(2024, 1, 15, 17, 0, tzinfo=tz)
df = client.recorded_values("SINUSOID", start=start, end=end)
TimeRange Class¶
The TimeRange class encapsulates a start and end time:
from pipolars.core.types import TimeRange, AFTime
# Create from explicit times
time_range = TimeRange(
start=AFTime("*-1d"),
end=AFTime("*")
)
# Use convenience methods
last_week = TimeRange.last(days=7)
today = TimeRange.today()
Interval Specifications¶
For interpolated values and summaries, specify intervals:
Interval |
Description |
|---|---|
|
1 hour |
|
30 minutes |
|
15 minutes |
|
1 day |
|
6 hours |
|
1 week |
with PIClient("my-pi-server") as client:
# Hourly interpolation
df = client.interpolated_values(
"SINUSOID", "*-1d", "*", interval="1h"
)
# 15-minute interpolation
df = client.interpolated_values(
"SINUSOID", "*-4h", "*", interval="15m"
)
# Daily summaries
df = client.summaries(
"SINUSOID", "*-30d", "*",
interval="1d",
summary_types=SummaryType.AVERAGE
)
Best Practices¶
Use relative expressions for scripts that run regularly:
# Good - always gets last 24 hours df = client.recorded_values("SINUSOID", "*-1d", "*")
Use absolute times for historical analysis:
# Good - specific date range df = client.recorded_values( "SINUSOID", "2024-01-01", "2024-01-31" )
Consider timezone when using datetime objects:
from zoneinfo import ZoneInfo # Always specify timezone for clarity tz = ZoneInfo("UTC") start = datetime(2024, 1, 15, tzinfo=tz)
Use appropriate intervals for interpolation:
Short ranges (< 1 day): Use minutes (5m, 15m)
Medium ranges (1-7 days): Use hours (1h, 4h)
Long ranges (> 7 days): Use days (1d)
Error Handling¶
Invalid time expressions raise PITimeParseError:
from pipolars.core.exceptions import PITimeParseError
try:
df = client.recorded_values("SINUSOID", "invalid", "*")
except PITimeParseError as e:
print(f"Invalid time expression: {e}")
Next Steps¶
Working with Polars DataFrames - Working with result DataFrames
Types - AFTime and TimeRange API reference