6

I have a datetime string with microsecond. I use the following script to get a QDateTime object and add it to a memory layer:

layer = QgsVectorLayer("Point?crs=EPSG:4326", "test", "memory")
layer.dataProvider().addAttributes([QgsField("dt", QVariant.DateTime)])
layer.updateFields()
QgsProject.instance().addMapLayer(layer, True)

s = "22/04/20 05:14:38:560000" # 560000 microsec = 560 millisec
# PyQt5 doesn't support microsec, so s[:-3]
dt = QDateTime.fromString(s[:-3], "yy/MM/dd HH:mm:ss:zzz").addYears(100)

feat = QgsFeature(layer.fields())
feat.setGeometry(QgsGeometry()) # empty geometry for test
feat["dt"] = dt

layer.dataProvider().addFeatures([feat])
layer.updateExtents()

But the millisecond part is missing in the attribute table.

enter image description here

How can I display the millisecond part in attribute table?

I do calculation at the level of milliseconds.

1

1 Answer 1

5

The comment by @Matt was already pointing in a correct direction. QgsDateTimeFieldFormatter is indeed needed to modify the display of DateTime values.

The following code example replaces the default DateTime formatter within the QgsFieldFormatterRegistry with a new formatter. The new formatter uses the given format string to parse any value.

class MyFormatter(QgsDateTimeFieldFormatter):
    
    config = {"display_format": "dd/MM/yyyy HH:mm:ss:zzz"} # your custom date time format
    
    def representValue(self, layer, fieldIndex, config, cache, value):
        return super().representValue(layer, fieldIndex, self.config, cache, value)
        

registry = QgsApplication.fieldFormatterRegistry()
registry.removeFieldFormatter('DateTime')
registry.addFieldFormatter(MyFormatter())

date_display

While writing this answer I just noticed that this approach removes the timezone string. I'm not sure at the moment on how to add it to the formatter.

Edit: As pointed out in the comments QgsDateTimeFieldFormatter formats all QDateTime, QDate and QTime values. In order to only modify the display of a single of those types implement a simple type check as below. QDate and QTime values should then stay the same.

def representValue(self, layer, fieldIndex, config, cache, value):
        if type(value) == QDateTime:
            return super().representValue(layer, fieldIndex, self.config, cache, value)
        
        return super().representValue(layer, fieldIndex, config, cache, value)
3
  • 1
    Thanks. Timezone is not necessary. It worked on DateTime format but it also changed only time (QTime) format to dd/MM/yyyy 10:20:32:000. It was displayed just 10:20:32 before this solution. I mean, this script adds dd/MM/yyy string and :000 to QTime value. -> i.stack.imgur.com/9lhr1.png May 21 at 0:47
  • And it adds 00:00:00:000 to QDate fields. -> i.stack.imgur.com/ckjLH.png May 21 at 0:56
  • @KadirŞahbaz Thanks for the notice. I didn't check other field types. I've updated my answer so that other values won't be modified. imgur.com/a/BR2gnnJ
    – CodeBard
    May 21 at 13:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.