Datetime 在SPARQL中确定日期时间的星期几

Datetime 在SPARQL中确定日期时间的星期几,datetime,sparql,Datetime,Sparql,我有一个图表,我正试图按星期几筛选报告。例如,我希望找到它们发生在星期二的所有实例。有没有办法将datetime字段格式化为星期几,或者直接在datetime字段上按星期几过滤?SPARQL没有day函数的名称,但是如果您的SPARQL端点是一个实例,您可以利用它的SQL函数。这是一个-- 我认为与其说是因为不知道如何构建SPARQL过滤器,不如说是因为缺少这样一个函数阻碍了您 (ObDisclaimer:products,and employees me。)SPARQL没有内置的“day of

我有一个图表,我正试图按星期几筛选报告。例如,我希望找到它们发生在星期二的所有实例。有没有办法将datetime字段格式化为星期几,或者直接在datetime字段上按星期几过滤?

SPARQL没有day函数的名称,但是如果您的SPARQL端点是一个实例,您可以利用它的SQL函数。这是一个--

我认为与其说是因为不知道如何构建SPARQL
过滤器,不如说是因为缺少这样一个函数阻碍了您


(ObDisclaimer:products,and employees me。)

SPARQL没有内置的“day of week”函数,但是,大多数编程语言都内置了从给定日历/日期对象检索day of week的支持。例如,使用Java和RDF4J,您可以简单地检索dateTime文本(用
xsd:dateTime
datatype表示为
literal
对象),转换为Java日历对象,然后检索工作日:

Literal值=…;//查询结果中的RDF4J文本值
日历=value.calendarValue().toGregorianCalendar();
int weekday=calendar.get(calendar.DAY/w);
此外,大多数SPARQL引擎提供添加自定义函数的选项


因此,您可以只检索dateTime并对结果进行后期处理以获取一周中的某一天,也可以实际创建一个自定义函数并将其添加到SPARQL引擎中。这里有一个关于的教程。

如果您提供了一些背景知识,还可以在标准SPARQL中确定一周中的哪一天。查询需要一个参考日期,该日期在您的日期之前,并在该日期的星期几

PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

SELECT ?date ?dayName
WHERE {
  # Sample dates
  VALUES ?date {
    "1961-08-04"^^xsd:date
    "1986-04-03"^^xsd:date
  }
  # Compute days since a reference date
  # This works in Virtuoso, which returns the difference in days.
  # For example, Fuseki returns xsd:duration instead.
  BIND (?date - "1900-01-01"^^xsd:date AS ?days)
  # Compute modulo by 7 without a modulo operator
  BIND (floor(?days - (7 * floor(?days/7))) AS ?mod)
  VALUES (?mod ?dayName) {
         (0    "Monday") # 1900-01-01 was Monday
         (6    "Tuesday")
         (5    "Wednesday")
         (4    "Thursday")
         (3    "Friday")
         (2    "Saturday")
         (1    "Sunday")
  }
}
前缀xsd:
选择?日期?日期名称
在哪里{
#样本日期
价值观?日期{
“1961-08-04”日期
“1986-04-03”日期
}
#计算自参考日期起的天数
#这在Virtuoso中起作用,它以天为单位返回差异。
#例如,Fuseki返回xsd:duration。
绑定(?日期-“1900-01-01”^^xsd:日期为?天)
#不使用模运算符计算7的模
绑定(地板(?天-(7*地板(?天/7)))为?mod)
值(?mod?dayName){
(0“星期一”)#1900-01-01是星期一
(6“星期二”)
(5“星期三”)
(4“星期四”)
(3“星期五”)
(2“星期六”)
(1“星期日”)
}
}

我使用了Jindrich的解决方案,并尝试使用
xsd:duration
算法重构它(与Virtuoso不同,它遵循SPARQL和XPath规范):

前缀xsd:
选择?日期?日期名称
在哪里{
#样本日期
价值观?日期{
“1961-08-04”日期
“1986-04-03”日期
}
绑定(xsd:date(?date)-“1900-01-01”^^xsd:date为?天)
绑定(?天-(xsd:dayTimeDuration(“P7D”)*地板(?天/xsd:dayTimeDuration(“P7D”))为?mod)
绑定(str(?mod)为?modStr)
值(?modStr?dayName){
(“PT0S”“星期一”)#1900-01-01是星期一
(“P1D”“星期二”)
(“P2D”“星期三”)
(“P3D”“星期四”)
(“P4D”“星期五”)
(“P5D”“星期六”)
(“P6D”“星期日”)
}
}

我在上运行了查询,得到了样本日期(星期五和星期四)的正确结果,但没有进一步测试。

根据这一点,该解决方案也适用于Virtuoso

目前,初始解决方案可以重新运行。根据这一点,演奏家也是如此

基本上,最初的答复是:

PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

SELECT ?date ?dayName
WHERE {
  # Sample dates
  VALUES ?date {
    "1961-08-04"^^xsd:date
    "1986-04-03"^^xsd:date
  }
  # Compute days since a reference date
  # This works in Virtuoso, which returns the difference in days.
  # For example, Fuseki returns xsd:duration instead.
  BIND (?date - "1900-01-01"^^xsd:date AS ?days)
  # Compute modulo by 7 without a modulo operator
  BIND (floor(?days - (7 * floor(?days/7))) AS ?mod)
  VALUES (?mod ?dayName) {
         (0    "Monday") # 1900-01-01 was Monday
         (6    "Tuesday")
         (5    "Wednesday")
         (4    "Thursday")
         (3    "Friday")
         (2    "Saturday")
         (1    "Sunday")
  }
}

# Catch occurrence of any cartesian product that can trick the human eye by adding ORDER BY CLAUSE 

ORDER BY DESC  
前缀xsd:
选择?日期?日期名称
在哪里{
#样本日期
价值观?日期{
“1961-08-04”日期
“1986-04-03”日期
}
#计算自参考日期起的天数
#这在Virtuoso中起作用,它以天为单位返回差异。
#例如,Fuseki返回xsd:duration。
绑定(?日期-“1900-01-01”^^xsd:日期为?天)
#不使用模运算符计算7的模
绑定(地板(?天-(7*地板(?天/7)))为?mod)
值(?mod?dayName){
(0“星期一”)#1900-01-01是星期一
(6“星期二”)
(5“星期三”)
(4“星期四”)
(3“星期五”)
(2“星期六”)
(1“星期日”)
}
}
#通过添加ORDER by子句捕捉任何笛卡尔积的出现,这些笛卡尔积可以欺骗人眼
按说明订购

以下是一个修订版,它通过应用用于禁用查询优化器的杂注来生成正确的解决方案

DEFINE sql:disable-optimizations 16
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

SELECT ?date ?dayName
WHERE {
  # Sample dates
  VALUES ?date {
    "1961-08-04"^^xsd:date
    "1986-04-03"^^xsd:date
  }
  BIND (xsd:date(?date) - "1900-01-01"^^xsd:date AS ?days)
  BIND (bif:mod (?days, xsd:dayTimeDuration("P7D")) AS ?mod)
  VALUES (?mod ?dayName) {
         ("PT0S"^^xsd:dayTimeDuration "Monday") # 1900-01-01 was Monday
         ("P1D"^^xsd:dayTimeDuration    "Tuesday")
         ("P2D"^^xsd:dayTimeDuration    "Wednesday")
         ("P3D"^^xsd:dayTimeDuration    "Thursday")
         ("P4D"^^xsd:dayTimeDuration    "Friday")
         ("P5D"^^xsd:dayTimeDuration    "Saturday")
         ("P6D"^^xsd:dayTimeDuration    "Sunday")
  }
}
ORDER BY DESC (?date)

定义sql:禁用优化16
前缀xsd:
选择?日期?日期名称
在哪里{
#样本日期
价值观?日期{
“1961-08-04”日期
“1986-04-03”日期
}
绑定(xsd:date(?date)-“1900-01-01”^^xsd:date为?天)
绑定(bif:mod(?天,xsd:dayTimeDuration(“P7D”))为?mod)
值(?mod?dayName){
(“PT0S”^^xsd:dayTimeDuration“星期一”)#1900-01-01是星期一
(“P1D”^^xsd:dayTimeDuration“星期二”)
(“P2D”^^xsd:dayTimeDuration“星期三”)
(“P3D”^^xsd:dayTimeDuration“星期四”)
(“P4D”^^xsd:dayTimeDuration“星期五”)
(“P5D”^^xsd:dayTimeDuration“星期六”)
(“P6D”^^xsd:dayTimeDuration“Sunday”)
}
}
按描述订购(?日期)

谢谢Jeen,这正是我所想的,但我想确保:)请注意,此“编程语言”选项确实将过滤带到了数据库引擎之外,这可能会大大增加处理时间和传输数据量。在你眼前的情况下,这可能是一个值得的折衷,但通常不会。事实上,因为我使用的是演奏家,所以这也是非常有帮助的!在长期使用SQL之后,我正在深入研究SPARQL,因此我开始在SPARQL中了解我习惯于在SQL/代码中所做的事情。如果Virtuoso能够正确地实现规范,那么就不需要任何扩展函数。@MartynasJusevičius-如果您能够登录,我们将不胜感激,这显然是对规范y的背离
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

SELECT ?date ?dayName
WHERE {
  # Sample dates
  VALUES ?date {
    "1961-08-04"^^xsd:date
    "1986-04-03"^^xsd:date
  }
  BIND (xsd:date(?date) - "1900-01-01"^^xsd:date AS ?days)
  BIND (?days - (xsd:dayTimeDuration("P7D") * floor(?days / xsd:dayTimeDuration("P7D"))) AS ?mod)
  BIND (str(?mod) AS ?modStr)
  VALUES (?modStr ?dayName) {
         ("PT0S"   "Monday") # 1900-01-01 was Monday
         ("P1D"    "Tuesday")
         ("P2D"    "Wednesday")
         ("P3D"    "Thursday")
         ("P4D"    "Friday")
         ("P5D"    "Saturday")
         ("P6D"    "Sunday")
  }
}
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

SELECT ?date ?dayName
WHERE {
  # Sample dates
  VALUES ?date {
    "1961-08-04"^^xsd:date
    "1986-04-03"^^xsd:date
  }
  # Compute days since a reference date
  # This works in Virtuoso, which returns the difference in days.
  # For example, Fuseki returns xsd:duration instead.
  BIND (?date - "1900-01-01"^^xsd:date AS ?days)
  # Compute modulo by 7 without a modulo operator
  BIND (floor(?days - (7 * floor(?days/7))) AS ?mod)
  VALUES (?mod ?dayName) {
         (0    "Monday") # 1900-01-01 was Monday
         (6    "Tuesday")
         (5    "Wednesday")
         (4    "Thursday")
         (3    "Friday")
         (2    "Saturday")
         (1    "Sunday")
  }
}

# Catch occurrence of any cartesian product that can trick the human eye by adding ORDER BY CLAUSE 

ORDER BY DESC  
DEFINE sql:disable-optimizations 16
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

SELECT ?date ?dayName
WHERE {
  # Sample dates
  VALUES ?date {
    "1961-08-04"^^xsd:date
    "1986-04-03"^^xsd:date
  }
  BIND (xsd:date(?date) - "1900-01-01"^^xsd:date AS ?days)
  BIND (bif:mod (?days, xsd:dayTimeDuration("P7D")) AS ?mod)
  VALUES (?mod ?dayName) {
         ("PT0S"^^xsd:dayTimeDuration "Monday") # 1900-01-01 was Monday
         ("P1D"^^xsd:dayTimeDuration    "Tuesday")
         ("P2D"^^xsd:dayTimeDuration    "Wednesday")
         ("P3D"^^xsd:dayTimeDuration    "Thursday")
         ("P4D"^^xsd:dayTimeDuration    "Friday")
         ("P5D"^^xsd:dayTimeDuration    "Saturday")
         ("P6D"^^xsd:dayTimeDuration    "Sunday")
  }
}
ORDER BY DESC (?date)