GRValidator Implemented E8

Error 8

E8: Check that all opening hour specs are non-overlapping for the same day of week, and that they make sense.

Validator Tool: Step # 10

Error Message

None ranges opens-closes values in opening hours specifications are include in others.

Potential Problem

One offering (gr:Offering) can include provision locations with more than one opening hour specification. Opening hour specifications can include open-close intervals using the gr:opens - gr:closes properties. Care must be taken that open-close ranges in opening hour specifications for the same location do not overlapp to each other.

Examples of Wrong Data

@prefix foo: <http://www.example.com/#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix gr: <http://purl.org/goodrelations/v1#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
foo:myCompany rdf:type gr:BusinessEntity ;
    gr:legalName "Hepp's Bagel Bakery Ltd. "^^<http://www.w3.org/2001/XMLSchema#string> ;
    vcard:fn "Hepp's Bagel Bakery Ltd. "@en .
foo:myShop rdf:type gr:LocationOfSalesOrServiceProvisioning ;
    vcard:adr foo:address ;
    vcard:tel "+49-89-6004-4217"^^<http://www.w3.org/2001/XMLSchema#string> .
foo:Workdays rdf:type gr:OpeningHoursSpecification ;
    gr:opens "08:00:00"^^<http://www.w3.org/2001/XMLSchema#time> ;
    gr:closes "18:00:00"^^<http://www.w3.org/2001/XMLSchema#time> ;
    gr:hasOpeningHoursDayOfWeek gr:Monday ,
        gr:Tuesday ,
        gr:Wednesday ,
        gr:Thursday ,
        gr:Friday .
foo:myShop gr:hasOpeningHourSpecification foo:Workdays .
foo:WorkdaysMonday rdf:type gr:OpeningHoursSpecification ;
    gr:opens "10:00:00"^^<http://www.w3.org/2001/XMLSchema#time> ;
    gr:closes "20:00:00"^^<http://www.w3.org/2001/XMLSchema#time> ;
    gr:hasOpeningHoursDayOfWeek gr:Monday .
foo:myShop gr:hasOpeningHourSpecification foo:WorkdaysMonday .
foo:Saturdays rdf:type gr:OpeningHoursSpecification ;
    gr:opens "08:30:00"^^<http://www.w3.org/2001/XMLSchema#time> ;
    gr:closes "14:00:00"^^<http://www.w3.org/2001/XMLSchema#time> ;
    gr:hasOpeningHoursDayOfWeek gr:Saturday .
foo:myShop gr:hasOpeningHourSpecification foo:Saturdays .
foo:myCompany gr:hasPOS foo:myShop ;
    rdfs:seeAlso <http://www.example.com/> .
foo:address rdf:type vcard:Address ;
    vcard:country-name "Germany"@en ;
    vcard:locality "Neubiberg"@en ;
    vcard:postal-code "85577"^^<http://www.w3.org/2001/XMLSchema#string> ;
    vcard:region "Bavaria"@en ;
    vcard:street-address "1234 Hepp Road"@en .
foo:myCompany vcard:adr foo:address ;
    vcard:tel "+49-89-6004-0"^^<http://www.w3.org/2001/XMLSchema#string> ;
    vcard:url <http://www.example.com/> .

SPARQL Query

PREFIX gr:<http://purl.org/goodrelations/v1#>

SELECT DISTINCT ?location
WHERE {
  {
    #Hours specification
    ?location gr:hasOpeningHourSpecification ?hoursSpec .
    ?hoursSpec gr:opens ?opens .
    ?hoursSpec gr:closes ?closes .
    ?hoursSpec gr:hasOpeningHoursDayOfWeek ?day .
    #Hours specification again
    ?location gr:hasOpeningHourSpecification ?hoursSpec1 .
    ?hoursSpec1 gr:opens ?opens1 .
    ?hoursSpec1 gr:closes ?closes1 .
    ?hoursSpec1 gr:hasOpeningHoursDayOfWeek ?day1 .
    #Not the same specification
    FILTER (( ?hoursSpec != ?hoursSpec1 ) && ( ?day = ?day1 ) )
    #overlaping hours
    FILTER (
      ( ( str(?opens) <= str(?closes1) ) && ( str(?closes1) <= str(?closes) ) ) ||
      ( ( str(?opens) <= str(?opens1) ) && ( str(?opens1) <= str(?closes) ) )
    )
  }
}
 ORDER BY ?location