diff --git a/CHANGELOG.md b/CHANGELOG.md
index f0143f3d049d95f9f66034772e847d6ecdc34155..613ee3150ee520199828e2bc7c875c4a924983e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -55,6 +55,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
   returned without ID but with a notice now.
 - #11 - pam_authentication leaks the password to unprivileged processes on the
   same machine.
+- #39 - quotes around datetimes in queries
 
 ### Security (in case of vulnerabilities)
 
diff --git a/src/main/java/caosdb/server/query/CQLParser.g4 b/src/main/java/caosdb/server/query/CQLParser.g4
index af981d6a2d027892c144070323aa924a5d7674a5..8b5e5a94aaea5d62ba60068a1ad652f7b51f1bd4 100644
--- a/src/main/java/caosdb/server/query/CQLParser.g4
+++ b/src/main/java/caosdb/server/query/CQLParser.g4
@@ -4,6 +4,8 @@
  *
  * Copyright (C) 2018 Research Group Biomedical Physics,
  * Max-Planck-Institute for Dynamics and Self-Organization Göttingen
+ * Copyright (C) 2020 Indiscale GmbH <info@indiscale.com>
+ * Copyright (C) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Affero General Public License as
@@ -188,11 +190,11 @@ username returns [Query.Pattern ep] locals [int type]
 
 transaction_time returns [String tqp]
 :
-	(
-		(ON | IN) 
-		(datetime {$tqp = $datetime.text;} 
-		| entity {$tqp = $entity.ep.toString();})
-	) | TODAY {$tqp = TransactionFilter.TODAY;} 
+    (
+        (ON | IN)
+        (value {$tqp = $value.text;}
+        | entity {$tqp = $entity.ep.toString();})
+    ) | TODAY {$tqp = TransactionFilter.TODAY;}
 ;
 
 /*
@@ -244,8 +246,8 @@ pov returns [POV filter] locals [Query.Pattern p, String o, String v, String a]
 			)
 			| IS_NULL {$o = "0";}
 			| IS_NOT_NULL {$o = "!0";}
-			| IN datetime {$o = "("; $v=$datetime.text;}
-			| NEGATION IN datetime {$o = "!("; $v=$datetime.text;}
+			| IN value {$o = "("; $v=$value.str;}
+			| NEGATION IN value {$o = "!("; $v=$value.str;}
 		)?
 	) 
 	| 
@@ -443,7 +445,7 @@ minmax returns [String agg]
 value returns [String str]
 : 
 	number {$str = $text;}
-	| datetime {$str = $text;}
+	| datetime {$str = $datetime.text;}
 	| atom {$str = $atom.ep.toString();}
 ;
 
diff --git a/src/main/java/caosdb/server/query/POV.java b/src/main/java/caosdb/server/query/POV.java
index a50be918da30d6cb69b457ef4b7801ea3019d58d..924c1293bfea78ef15f1b6ab10e5d9d91a2a98cc 100644
--- a/src/main/java/caosdb/server/query/POV.java
+++ b/src/main/java/caosdb/server/query/POV.java
@@ -167,6 +167,9 @@ public class POV implements EntityFilterInterface {
       } catch (final ClassCastException e) {
         this.vDatetime = null;
       } catch (final IllegalArgumentException e) {
+        if (this.operator.contains("(")) {
+          throw new Query.ParsingException("the value is expected to be a date time");
+        }
         this.vDatetime = null;
       }
     } else {
diff --git a/src/test/java/caosdb/server/query/TestCQL.java b/src/test/java/caosdb/server/query/TestCQL.java
index 6006297dac0cd029ee451c0349f2b11e7ac2f86e..402cddd2be631291d772d494804cf21bc9dbc6b7 100644
--- a/src/test/java/caosdb/server/query/TestCQL.java
+++ b/src/test/java/caosdb/server/query/TestCQL.java
@@ -167,8 +167,11 @@ public class TestCQL {
   String ticket187 = "FIND Entity WITH pname=-1";
   String ticket207 = "FIND RECORD WHICH REFERENCES 10594";
   String query33 = "FIND ename WITH a date IN 2015";
+  String query33a = "FIND ename WITH a date IN \"2015\"";
   String query34 = "FIND ename WITH a date NOT IN 2015";
+  String query34a = "FIND ename WITH a date NOT IN \"2015\"";
   String query35 = "FIND ename WITH a date IN 2015-01-01";
+  String query35a = "FIND ename WITH a date IN \"2015-01-01\"";
   String query36 = "FIND ename.pname LIKE \"wil*card\"";
   String query37 = "FIND ename.pname LIKE wil*card";
   String query38 = "FIND ename WHICH HAS A pname LIKE \"wil*\"";
@@ -4671,6 +4674,45 @@ public class TestCQL {
     assertEquals("2015", pov.getValue());
   }
 
+  /** String query33a = "FIND ename WITH a date IN \"2015\""; */
+  @Test
+  public void testQuery33a() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.query33a));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    // 4 children: FIND, role, WHICHCLAUSE, EOF
+    assertEquals(4, sfq.getChildCount());
+    assertEquals("FIND", sfq.getChild(0).getText());
+    assertEquals("ename", sfq.getChild(1).getText());
+    assertEquals("WITHadateIN\"2015\"", sfq.getChild(2).getText());
+    assertEquals("ename", sfq.e.toString());
+    assertNull(sfq.r);
+    assertEquals("POV", sfq.filter.getClass().getSimpleName());
+
+    final ParseTree whichclause = sfq.getChild(2);
+    // 2 children; WHICH, transaction
+    assertEquals(2, whichclause.getChildCount());
+    assertEquals("WITHa", whichclause.getChild(0).getText());
+    assertEquals("dateIN\"2015\"", whichclause.getChild(1).getText());
+
+    final ParseTree transactionFilter = whichclause.getChild(1).getChild(0);
+    assertEquals(3, transactionFilter.getChildCount());
+    assertEquals("date", transactionFilter.getChild(0).getText());
+    assertEquals("IN", transactionFilter.getChild(1).getText());
+    assertEquals("\"2015\"", transactionFilter.getChild(2).getText());
+
+    assertTrue(sfq.filter instanceof POV);
+    final POV pov = (POV) sfq.filter;
+    assertEquals("(", pov.getOperator());
+    assertEquals("2015", pov.getValue());
+  }
+
   /** String query34 = "FIND ename WITH a date NOT IN 2015"; */
   @Test
   public void testQuery34() {
@@ -4711,6 +4753,46 @@ public class TestCQL {
     assertEquals("2015", pov.getValue());
   }
 
+  /** String query34a = "FIND ename WITH a date NOT IN \"2015\""; */
+  @Test
+  public void testQuery34a() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.query34a));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    // 4 children: FIND, role, WHICHCLAUSE, EOF
+    assertEquals(4, sfq.getChildCount());
+    assertEquals("FIND", sfq.getChild(0).getText());
+    assertEquals("ename", sfq.getChild(1).getText());
+    assertEquals("WITHadateNOTIN\"2015\"", sfq.getChild(2).getText());
+    assertEquals("ename", sfq.e.toString());
+    assertNull(sfq.r);
+    assertEquals("POV", sfq.filter.getClass().getSimpleName());
+
+    final ParseTree whichclause = sfq.getChild(2);
+    // 2 children: WHICH, POV
+    assertEquals(2, whichclause.getChildCount());
+    assertEquals("WITHa", whichclause.getChild(0).getText());
+    assertEquals("dateNOTIN\"2015\"", whichclause.getChild(1).getText());
+
+    final ParseTree transactionFilter = whichclause.getChild(1).getChild(0);
+    assertEquals(4, transactionFilter.getChildCount());
+    assertEquals("date", transactionFilter.getChild(0).getText());
+    assertEquals("NOT", transactionFilter.getChild(1).getText());
+    assertEquals("IN", transactionFilter.getChild(2).getText());
+    assertEquals("\"2015\"", transactionFilter.getChild(3).getText());
+
+    assertTrue(sfq.filter instanceof POV);
+    final POV pov = (POV) sfq.filter;
+    assertEquals("!(", pov.getOperator());
+    assertEquals("2015", pov.getValue());
+  }
+
   /** String query35 = "FIND ename WITH a date IN 2015-01-01"; */
   @Test
   public void testQuery35() {
@@ -4750,6 +4832,45 @@ public class TestCQL {
     assertEquals("2015-01-01", pov.getValue());
   }
 
+  /** String query35a = "FIND ename WITH a date IN \"2015-01-01\""; */
+  @Test
+  public void testQuery35a() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.query35a));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    // 4 children: FIND, role, WHICHCLAUSE, EOF
+    assertEquals(4, sfq.getChildCount());
+    assertEquals("FIND", sfq.getChild(0).getText());
+    assertEquals("ename", sfq.getChild(1).getText());
+    assertEquals("WITHadateIN\"2015-01-01\"", sfq.getChild(2).getText());
+    assertEquals("ename", sfq.e.toString());
+    assertNull(sfq.r);
+    assertEquals("POV", sfq.filter.getClass().getSimpleName());
+
+    final ParseTree whichclause = sfq.getChild(2);
+    // 2 children: WHICH, POV
+    assertEquals(2, whichclause.getChildCount());
+    assertEquals("WITHa", whichclause.getChild(0).getText());
+    assertEquals("dateIN\"2015-01-01\"", whichclause.getChild(1).getText());
+
+    final ParseTree transactionFilter = whichclause.getChild(1).getChild(0);
+    assertEquals(3, transactionFilter.getChildCount());
+    assertEquals("date", transactionFilter.getChild(0).getText());
+    assertEquals("IN", transactionFilter.getChild(1).getText());
+    assertEquals("\"2015-01-01\"", transactionFilter.getChild(2).getText());
+
+    assertTrue(sfq.filter instanceof POV);
+    final POV pov = (POV) sfq.filter;
+    assertEquals("(", pov.getOperator());
+    assertEquals("2015-01-01", pov.getValue());
+  }
+
   /** String query36 = "FIND ename.pname LIKE \"wil*card\""; */
   @Test
   public void testQuery36() {