I just received this question over the phone. You can do it using a script like the following (this one is an active script on a set point event handler)

var dsxid = "DS_Poll_Test";
var dsvo = com.serotonin.m2m2.db.dao.DataSourceDao.instance.getByXid(dsxid);
var dsrt = com.serotonin.m2m2.Common.runtimeManager.getRunningDataSource(dsvo.getId());
//It must be a polling data source for this to work
var pollTimes = dsrt.getLatestPollTimes();
TIMESTAMP = pollTimes[pollTimes.length-1].key; //Set the time for the value to the time of the poll
return pollTimes[pollTimes.length-1].value; //get the duration in milliseconds

And here is the JSON from the test configuration:

{
   "dataSources":[
      {
         "xid":"DS_Poll_Test",
         "name":"vrt",
         "enabled":true,
         "type":"VIRTUAL",
         "alarmLevels":{
            "POLL_ABORTED":"URGENT"
         },
         "purgeType":"YEARS",
         "updatePeriodType":"SECONDS",
         "polling":true,
         "updatePeriods":5,
         "editPermission":"",
         "purgeOverride":false,
         "purgePeriod":1
      }
   ],
   "dataPoints":[
      {
         "xid":"DP_95f3a171-1183-4eb0-81d5-d18413b1568f",
         "name":"Changer",
         "enabled":true,
         "loggingType":"ON_CHANGE",
         "intervalLoggingPeriodType":"MINUTES",
         "intervalLoggingType":"INSTANT",
         "purgeType":"YEARS",
         "pointLocator":{
            "dataType":"BINARY",
            "changeType":{
               "type":"ALTERNATE_BOOLEAN",
               "startValue":"true"
            },
            "settable":false
         },
         "eventDetectors":[
            {
               "type":"POINT_CHANGE",
               "sourceType":"DATA_POINT",
               "xid":"ED_d122a920-68ce-416c-b2bf-bd32a868a42d",
               "alias":"Trigger the poll time script",
               "alarmLevel":"DO_NOT_LOG"
            }
         ],
         "plotType":"STEP",
         "rollup":"NONE",
         "unit":"",
         "templateXid":"Binary_Default",
         "chartColour":"",
         "chartRenderer":{
            "type":"TABLE",
            "limit":10
         },
         "dataSourceXid":"DS_Poll_Test",
         "defaultCacheSize":1,
         "deviceName":"vrt",
         "discardExtremeValues":false,
         "discardHighLimit":1.7976931348623157E308,
         "discardLowLimit":-1.7976931348623157E308,
         "intervalLoggingPeriod":15,
         "intervalLoggingSampleWindowSize":0,
         "overrideIntervalLoggingSamples":false,
         "preventSetExtremeValues":false,
         "purgeOverride":false,
         "purgePeriod":1,
         "readPermission":"",
         "setExtremeHighLimit":1.7976931348623157E308,
         "setExtremeLowLimit":-1.7976931348623157E308,
         "setPermission":"",
         "textRenderer":{
            "type":"BINARY",
            "oneColour":"black",
            "oneLabel":"one",
            "zeroColour":"blue",
            "zeroLabel":"zero"
         },
         "tolerance":0.0
      },
      {
         "xid":"DP_e8d0ea46-b514-4230-aae8-63e38adce6d7",
         "name":"Poll Times",
         "enabled":true,
         "loggingType":"ALL",
         "intervalLoggingPeriodType":"MINUTES",
         "intervalLoggingType":"AVERAGE",
         "purgeType":"YEARS",
         "pointLocator":{
            "dataType":"NUMERIC",
            "changeType":{
               "type":"NO_CHANGE",
               "startValue":"-1"
            },
            "settable":true
         },
         "eventDetectors":[
         ],
         "plotType":"SPLINE",
         "rollup":"NONE",
         "unit":"",
         "chartColour":"",
         "chartRenderer":{
            "type":"IMAGE",
            "timePeriodType":"DAYS",
            "numberOfPeriods":1
         },
         "dataSourceXid":"DS_Poll_Test",
         "defaultCacheSize":1,
         "deviceName":"vrt",
         "discardExtremeValues":false,
         "discardHighLimit":1.7976931348623157E308,
         "discardLowLimit":-1.7976931348623157E308,
         "intervalLoggingPeriod":1,
         "intervalLoggingSampleWindowSize":0,
         "overrideIntervalLoggingSamples":false,
         "preventSetExtremeValues":false,
         "purgeOverride":false,
         "purgePeriod":1,
         "readPermission":"",
         "setExtremeHighLimit":1.7976931348623157E308,
         "setExtremeLowLimit":-1.7976931348623157E308,
         "setPermission":"",
         "textRenderer":{
            "type":"ANALOG",
            "useUnitAsSuffix":true,
            "unit":"",
            "renderedUnit":"",
            "format":"0.00"
         },
         "tolerance":0.0
      }
   ],
   "eventHandlers":[
      {
         "eventType":{
            "sourceType":"DATA_POINT",
            "dataPointXID":"DP_95f3a171-1183-4eb0-81d5-d18413b1568f",
            "detectorXID":"ED_d122a920-68ce-416c-b2bf-bd32a868a42d"
         },
         "xid":"EH_96f7b068-4515-4cd3-99f6-cfe94df14acb",
         "handlerType":"SET_POINT",
         "targetPointId":"DP_e8d0ea46-b514-4230-aae8-63e38adce6d7",
         "activeAction":"SCRIPT_VALUE",
         "activeScript":"var dsxid = \"DS_Poll_Test\";\nvar dsvo = com.serotonin.m2m2.db.dao.DataSourceDao.instance.getByXid(dsxid);\nvar dsrt = com.serotonin.m2m2.Common.runtimeManager.getRunningDataSource(dsvo.getId());\n\/\/It must be a polling data source for this to work\nvar pollTimes = dsrt.getLatestPollTimes();\nTIMESTAMP = pollTimes[pollTimes.length-1].key;\nreturn pollTimes[pollTimes.length-1].value;",
         "inactiveAction":"NONE",
         "additionalContext":[
         ],
         "scriptPermissions":{
            "scriptDataPointReadPermission":"",
            "scriptDataPointSetPermission":"",
            "scriptDataSourcePermission":""
         },
         "alias":"",
         "disabled":false
      }
   ]
}

There is a blemish in that the poll times data point will have two values for each poll (I set it to log all data because the poll time for the virtual source is always zero, and I have the trigger on the data source, so I can't just enable polling) but that is easily fixed if you wish to do this for your own data source(s).

Edit: Thinking about it again, i may use that script in a meta point, with a polled point on the source as the context update, and an execution delay to assure the event is not processed before the poll is finished. Or one may process the list on a cron to assure they didn't miss any.