Time Expressions - PIPolars 0.1.0 documentation

Skip to content
Back to top
View this page
Edit this page

# 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)
`*-1h` | 1 hour ago
`*-1d` | 1 day ago
`*-7d` | 7 days ago
`*-30d` | 30 days ago
`*-1w` | 1 week ago
`*-2M` | 2 months ago
`*-1y` | 1 year ago
`*+1h` | 1 hour from now
`*-1d+6h` | 1 day ago plus 6 hours

### Named Time Expressions

Expression | Description
--- | ---
`t` | Today at midnight (start of day)
`y` | Yesterday at midnight
`t+8h` | Today at 8:00 AM
`y+17h` | Yesterday at 5:00 PM
`t-1d` | Start of yesterday (same as `y`)

### Absolute Time Expressions

Expression | Description
--- | ---
`2024-01-15` | January 15, 2024 at midnight
`2024-01-15T10:30:00` | January 15, 2024 at 10:30:00
`2024-01-15 10:30:00` | Same (with space separator)
`15-Jan-2024` | Alternative date format
`01/15/2024` | 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
--- | ---
`1h` | 1 hour
`30m` | 30 minutes
`15m` | 15 minutes
`1d` | 1 day
`6h` | 6 hours
`1w` | 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

1. Use relative expressions for scripts that run regularly:

       # Good - always gets last 24 hours
       df = client.recorded_values("SINUSOID", "*-1d", "*")

2. Use absolute times for historical analysis:

       # Good - specific date range
       df = client.recorded_values(
           "SINUSOID",
           "2024-01-01",
           "2024-01-31"
       )

3. 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)

4. 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