How to Use Date Shifting for HIPAA Safe Harbor Compliance in OpenMed

OpenMed's shift_dates method shifts detected dates by a configurable offset while preserving intervals, satisfying HIPAA Safe Harbor requirements for date de-identification.

The OpenMed library provides HIPAA-compliant de-identification tools for clinical text. When processing protected health information (PHI), the HIPAA Safe Harbor method requires all dates to be altered by a random offset while maintaining relative intervals between events. OpenMed's shift_dates method implements this requirement through a configurable date-shifting algorithm that handles multiple international formats.

Understanding the HIPAA Safe Harbor Date Requirement

HIPAA Safe Harbor de-identification standards mandate that dates relating to an individual must be changed to obscure the exact calendar day. However, the standard specifically requires that these changes use a random offset that preserves the intervals between dates. This ensures that temporal relationships—such as the number of days between admission and discharge—remain intact for research or analysis purposes while protecting patient privacy.

How OpenMed Implements Date Shifting

The implementation spans three architectural layers in the maziyarpanahi/openmed repository.

Request Validation and Schema Handling

In openmed/service/schemas.py (lines 58-70), the Pydantic request models normalize the legacy shift_dates boolean flag and enforce that date_shift_days is only accepted when the method is explicitly set to "shift_dates". This validation ensures that date shifting parameters are properly isolated from other de-identification methods.

Core Redaction Logic

The dispatcher in openmed/core/pii.py (lines 903-910) routes entities to the appropriate redaction routine. When the configuration specifies "shift_dates", the system invokes the internal _shift_date helper function rather than applying standard masking or replacement techniques.

The Date Shifting Algorithm

The _shift_date function in openmed/core/pii.py (lines 1124-1190) supports US, European, ISO, and localized month-name date formats. The algorithm first attempts language-aware parsing, falls back to regex-based extraction when dateutil is unavailable, and formats the output to match the original style. The function respects the optional keep_year parameter (default True), which preserves the original year while shifting only the month and day—useful for maintaining patient age while obscuring specific dates.

Practical Implementation Examples

You can invoke date shifting through the HTTP API or directly via Python functions.

HTTP API Requests

Send a POST request to the /pii/deidentify endpoint with the method set to "shift_dates" and specify your offset in date_shift_days:

{
  "text": "Patient was admitted on 03/15/2021 and discharged on 03/20/2021.",
  "method": "shift_dates",
  "date_shift_days": 180,
  "keep_year": false
}

For backward compatibility, OpenMed also accepts the legacy boolean flag, automatically promoting it to the new method:

{
  "text": "Patient was admitted on 03/15/2021.",
  "shift_dates": true,
  "date_shift_days": 30
}

Both payloads shift detected dates by the specified number of days while masking non-date PII entities like names.

Python Client Integration

Use the requests library to call the de-identification endpoint programmatically:

import requests

payload = {
    "text": "The surgery took place on 2020-01-15.",
    "method": "shift_dates",
    "date_shift_days": 90,
    "keep_year": True,
}
resp = requests.post(
    "http://localhost:8000/pii/deidentify",
    json=payload,
)
print(resp.json()["text"])

# → "The surgery took place on 03/15/2020."

Direct Helper Usage

For custom pipelines, import the internal helper directly from the core module:

from openmed.core.pii import _shift_date

original = "15.01.2020"          # German format DD.MM.YYYY

shifted = _shift_date(original, shift_days=30, keep_year=False, lang="de")
print(shifted)                   # → "14.02.2020"

Configuration Options and Parameters

The date shifting behavior is controlled through these key parameters:

  • method: Must be set to "shift_dates" to enable the shifting algorithm.
  • date_shift_days: Integer specifying the number of days to shift (positive or negative).
  • keep_year: Boolean flag (default True) that preserves the original year when set to True, shifting only month and day.

Summary

  • OpenMed implements HIPAA Safe Harbor date shifting through the "shift_dates" method in openmed/core/pii.py.
  • The _shift_date function handles multiple international date formats with language-aware parsing and regex fallback.
  • Request validation in openmed/service/schemas.py ensures proper parameter isolation.
  • The keep_year option allows preservation of patient age while obscuring exact dates.
  • Both HTTP API and direct Python integration paths are supported.

Frequently Asked Questions

What is the HIPAA Safe Harbor requirement for dates?

HIPAA Safe Harbor requires that all dates relating to an individual be changed by a random offset. The standard specifically mandates that this offset must preserve the intervals between dates, meaning the relative time between events remains calculable while the absolute calendar dates are obscured.

How does OpenMed preserve date intervals when shifting?

OpenMed applies the same date_shift_days offset to every detected date within a single document. Since all dates shift by identical day counts, the difference between any two dates remains constant, satisfying the interval preservation requirement of the Safe Harbor method.

Can I keep the original year while shifting dates?

Yes. Set the keep_year parameter to True (the default). When enabled, the _shift_date algorithm in openmed/core/pii.py shifts only the month and day components while retaining the original year, which is useful for maintaining patient age demographics while de-identifying specific calendar dates.

What date formats does OpenMed support for shifting?

The implementation supports US formats (MM/DD/YYYY), European formats (DD.MM.YYYY), ISO 8601 (YYYY-MM-DD), and localized month-name variants. The algorithm attempts language-aware parsing first, then falls back to regex-based extraction if dateutil is unavailable, ensuring broad compatibility with clinical text formats.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →